diff --git a/xos/core/xoslib/ngXosLib/api/.gitignore b/xos/core/xoslib/ngXosLib/api/.gitignore
new file mode 100644
index 0000000..c96a04f
--- /dev/null
+++ b/xos/core/xoslib/ngXosLib/api/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
\ No newline at end of file
diff --git a/xos/core/xoslib/ngXosLib/api/ng-hpcapi.js b/xos/core/xoslib/ngXosLib/api/ng-hpcapi.js
deleted file mode 100644
index 0ed987c..0000000
--- a/xos/core/xoslib/ngXosLib/api/ng-hpcapi.js
+++ /dev/null
@@ -1,5443 +0,0 @@
-/*jshint -W069 */
-/*global angular:false */
-angular.module('xos.hpcapi', [])
-    .factory('hpcapi', ['$q', '$http', '$rootScope', function($q, $http, $rootScope) {
-        'use strict';
-
-        /**
-         * 
-         * @class hpcapi
-         * @param {(string|object)} [domainOrOptions] - The project domain or options object. If object, see the object's optional properties.
-         * @param {string} [domainOrOptions.domain] - The project domain
-         * @param {string} [domainOrOptions.cache] - An angularjs cache implementation
-         * @param {object} [domainOrOptions.token] - auth token - object with value property and optional headerOrQueryName and isQuery properties
-         * @param {string} [cache] - An angularjs cache implementation
-         */
-        var hpcapi = (function() {
-            function hpcapi(options, cache) {
-                var domain = (typeof options === 'object') ? options.domain : options;
-                this.domain = typeof(domain) === 'string' ? domain : 'http://localhost:9999';
-                if (this.domain.length === 0) {
-                    throw new Error('Domain parameter must be specified as a string.');
-                }
-                cache = cache || ((typeof options === 'object') ? options.cache : cache);
-                this.cache = cache;
-            }
-
-            hpcapi.prototype.$on = function($scope, path, handler) {
-                var url = domain + path;
-                $scope.$on(url, function() {
-                    handler();
-                });
-                return this;
-            };
-
-            hpcapi.prototype.$broadcast = function(path) {
-                var url = domain + path;
-                //cache.remove(url);
-                $rootScope.$broadcast(url);
-                return this;
-            };
-
-            hpcapi.transformRequest = function(obj) {
-                var str = [];
-                for (var p in obj) {
-                    var val = obj[p];
-                    if (angular.isArray(val)) {
-                        val.forEach(function(val) {
-                            str.push(encodeURIComponent(p) + "=" + encodeURIComponent(val));
-                        });
-                    } else {
-                        str.push(encodeURIComponent(p) + "=" + encodeURIComponent(val));
-                    }
-                }
-                return str.join("&");
-            };
-
-            /**
-             * 
-             * @method
-             * @name hpcapi#Hpc_Api_Root_GET
-             * 
-             */
-            hpcapi.prototype.Hpc_Api_Root_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Hpc_Health_Check_List_GET
-             * 
-             */
-            hpcapi.prototype.Hpc_Health_Check_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/hpchealthchecks/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Hpc_Health_Check_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} hpcService - 
-             * @param {choice} kind - 
-             * @param {string} resource_name - 
-             * @param {string} result_contains - 
-             * @param {integer} result_min_size - 
-             * @param {integer} result_max_size - 
-             * 
-             */
-            hpcapi.prototype.Hpc_Health_Check_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/hpchealthchecks/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['hpcService'] !== undefined) {
-                    form['hpcService'] = parameters['hpcService'];
-                }
-
-                if (parameters['kind'] !== undefined) {
-                    form['kind'] = parameters['kind'];
-                }
-
-                if (parameters['kind'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: kind'));
-                    return deferred.promise;
-                }
-
-                if (parameters['resource_name'] !== undefined) {
-                    form['resource_name'] = parameters['resource_name'];
-                }
-
-                if (parameters['resource_name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: resource_name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['result_contains'] !== undefined) {
-                    form['result_contains'] = parameters['result_contains'];
-                }
-
-                if (parameters['result_min_size'] !== undefined) {
-                    form['result_min_size'] = parameters['result_min_size'];
-                }
-
-                if (parameters['result_max_size'] !== undefined) {
-                    form['result_max_size'] = parameters['result_max_size'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Hpc_Health_Check_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            hpcapi.prototype.Hpc_Health_Check_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/hpchealthchecks/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Hpc_Health_Check_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} hpcService - 
-             * @param {choice} kind - 
-             * @param {string} resource_name - 
-             * @param {string} result_contains - 
-             * @param {integer} result_min_size - 
-             * @param {integer} result_max_size - 
-             * 
-             */
-            hpcapi.prototype.Hpc_Health_Check_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/hpchealthchecks/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['hpcService'] !== undefined) {
-                    form['hpcService'] = parameters['hpcService'];
-                }
-
-                if (parameters['kind'] !== undefined) {
-                    form['kind'] = parameters['kind'];
-                }
-
-                if (parameters['kind'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: kind'));
-                    return deferred.promise;
-                }
-
-                if (parameters['resource_name'] !== undefined) {
-                    form['resource_name'] = parameters['resource_name'];
-                }
-
-                if (parameters['resource_name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: resource_name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['result_contains'] !== undefined) {
-                    form['result_contains'] = parameters['result_contains'];
-                }
-
-                if (parameters['result_min_size'] !== undefined) {
-                    form['result_min_size'] = parameters['result_min_size'];
-                }
-
-                if (parameters['result_max_size'] !== undefined) {
-                    form['result_max_size'] = parameters['result_max_size'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Hpc_Health_Check_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} hpcService - 
-             * @param {choice} kind - 
-             * @param {string} resource_name - 
-             * @param {string} result_contains - 
-             * @param {integer} result_min_size - 
-             * @param {integer} result_max_size - 
-             * 
-             */
-            hpcapi.prototype.Hpc_Health_Check_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/hpchealthchecks/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['hpcService'] !== undefined) {
-                    form['hpcService'] = parameters['hpcService'];
-                }
-
-                if (parameters['kind'] !== undefined) {
-                    form['kind'] = parameters['kind'];
-                }
-
-                if (parameters['resource_name'] !== undefined) {
-                    form['resource_name'] = parameters['resource_name'];
-                }
-
-                if (parameters['result_contains'] !== undefined) {
-                    form['result_contains'] = parameters['result_contains'];
-                }
-
-                if (parameters['result_min_size'] !== undefined) {
-                    form['result_min_size'] = parameters['result_min_size'];
-                }
-
-                if (parameters['result_max_size'] !== undefined) {
-                    form['result_max_size'] = parameters['result_max_size'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Hpc_Health_Check_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            hpcapi.prototype.Hpc_Health_Check_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/hpchealthchecks/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Hpc_Service_List_GET
-             * 
-             */
-            hpcapi.prototype.Hpc_Service_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/hpcservices/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Hpc_Service_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} description - Description of Service
-             * @param {boolean} enabled - 
-             * @param {string} kind - Kind of service
-             * @param {string} name - Service Name
-             * @param {string} versionNumber - Version of Service Definition
-             * @param {boolean} published - 
-             * @param {string} view_url - 
-             * @param {string} icon_url - 
-             * @param {string} public_key - Public key string
-             * @param {string} service_specific_id - 
-             * @param {string} service_specific_attribute - 
-             * @param {string} cmi_hostname - 
-             * @param {boolean} hpc_port80 - Enable port 80 for HPC
-             * @param {string} watcher_hpc_network - Network for hpc_watcher to contact hpc instance
-             * @param {string} watcher_dnsdemux_network - Network for hpc_watcher to contact dnsdemux instance
-             * @param {string} watcher_dnsredir_network - Network for hpc_watcher to contact dnsredir instance
-             * 
-             */
-            hpcapi.prototype.Hpc_Service_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/hpcservices/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters['kind'] !== undefined) {
-                    form['kind'] = parameters['kind'];
-                }
-
-                if (parameters['kind'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: kind'));
-                    return deferred.promise;
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['versionNumber'] !== undefined) {
-                    form['versionNumber'] = parameters['versionNumber'];
-                }
-
-                if (parameters['versionNumber'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: versionNumber'));
-                    return deferred.promise;
-                }
-
-                if (parameters['published'] !== undefined) {
-                    form['published'] = parameters['published'];
-                }
-
-                if (parameters['view_url'] !== undefined) {
-                    form['view_url'] = parameters['view_url'];
-                }
-
-                if (parameters['icon_url'] !== undefined) {
-                    form['icon_url'] = parameters['icon_url'];
-                }
-
-                if (parameters['public_key'] !== undefined) {
-                    form['public_key'] = parameters['public_key'];
-                }
-
-                if (parameters['service_specific_id'] !== undefined) {
-                    form['service_specific_id'] = parameters['service_specific_id'];
-                }
-
-                if (parameters['service_specific_attribute'] !== undefined) {
-                    form['service_specific_attribute'] = parameters['service_specific_attribute'];
-                }
-
-                if (parameters['cmi_hostname'] !== undefined) {
-                    form['cmi_hostname'] = parameters['cmi_hostname'];
-                }
-
-                if (parameters['hpc_port80'] !== undefined) {
-                    form['hpc_port80'] = parameters['hpc_port80'];
-                }
-
-                if (parameters['watcher_hpc_network'] !== undefined) {
-                    form['watcher_hpc_network'] = parameters['watcher_hpc_network'];
-                }
-
-                if (parameters['watcher_dnsdemux_network'] !== undefined) {
-                    form['watcher_dnsdemux_network'] = parameters['watcher_dnsdemux_network'];
-                }
-
-                if (parameters['watcher_dnsredir_network'] !== undefined) {
-                    form['watcher_dnsredir_network'] = parameters['watcher_dnsredir_network'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Hpc_Service_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            hpcapi.prototype.Hpc_Service_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/hpcservices/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Hpc_Service_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} description - Description of Service
-             * @param {boolean} enabled - 
-             * @param {string} kind - Kind of service
-             * @param {string} name - Service Name
-             * @param {string} versionNumber - Version of Service Definition
-             * @param {boolean} published - 
-             * @param {string} view_url - 
-             * @param {string} icon_url - 
-             * @param {string} public_key - Public key string
-             * @param {string} service_specific_id - 
-             * @param {string} service_specific_attribute - 
-             * @param {string} cmi_hostname - 
-             * @param {boolean} hpc_port80 - Enable port 80 for HPC
-             * @param {string} watcher_hpc_network - Network for hpc_watcher to contact hpc instance
-             * @param {string} watcher_dnsdemux_network - Network for hpc_watcher to contact dnsdemux instance
-             * @param {string} watcher_dnsredir_network - Network for hpc_watcher to contact dnsredir instance
-             * 
-             */
-            hpcapi.prototype.Hpc_Service_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/hpcservices/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters['kind'] !== undefined) {
-                    form['kind'] = parameters['kind'];
-                }
-
-                if (parameters['kind'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: kind'));
-                    return deferred.promise;
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['versionNumber'] !== undefined) {
-                    form['versionNumber'] = parameters['versionNumber'];
-                }
-
-                if (parameters['versionNumber'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: versionNumber'));
-                    return deferred.promise;
-                }
-
-                if (parameters['published'] !== undefined) {
-                    form['published'] = parameters['published'];
-                }
-
-                if (parameters['view_url'] !== undefined) {
-                    form['view_url'] = parameters['view_url'];
-                }
-
-                if (parameters['icon_url'] !== undefined) {
-                    form['icon_url'] = parameters['icon_url'];
-                }
-
-                if (parameters['public_key'] !== undefined) {
-                    form['public_key'] = parameters['public_key'];
-                }
-
-                if (parameters['service_specific_id'] !== undefined) {
-                    form['service_specific_id'] = parameters['service_specific_id'];
-                }
-
-                if (parameters['service_specific_attribute'] !== undefined) {
-                    form['service_specific_attribute'] = parameters['service_specific_attribute'];
-                }
-
-                if (parameters['cmi_hostname'] !== undefined) {
-                    form['cmi_hostname'] = parameters['cmi_hostname'];
-                }
-
-                if (parameters['hpc_port80'] !== undefined) {
-                    form['hpc_port80'] = parameters['hpc_port80'];
-                }
-
-                if (parameters['watcher_hpc_network'] !== undefined) {
-                    form['watcher_hpc_network'] = parameters['watcher_hpc_network'];
-                }
-
-                if (parameters['watcher_dnsdemux_network'] !== undefined) {
-                    form['watcher_dnsdemux_network'] = parameters['watcher_dnsdemux_network'];
-                }
-
-                if (parameters['watcher_dnsredir_network'] !== undefined) {
-                    form['watcher_dnsredir_network'] = parameters['watcher_dnsredir_network'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Hpc_Service_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} description - Description of Service
-             * @param {boolean} enabled - 
-             * @param {string} kind - Kind of service
-             * @param {string} name - Service Name
-             * @param {string} versionNumber - Version of Service Definition
-             * @param {boolean} published - 
-             * @param {string} view_url - 
-             * @param {string} icon_url - 
-             * @param {string} public_key - Public key string
-             * @param {string} service_specific_id - 
-             * @param {string} service_specific_attribute - 
-             * @param {string} cmi_hostname - 
-             * @param {boolean} hpc_port80 - Enable port 80 for HPC
-             * @param {string} watcher_hpc_network - Network for hpc_watcher to contact hpc instance
-             * @param {string} watcher_dnsdemux_network - Network for hpc_watcher to contact dnsdemux instance
-             * @param {string} watcher_dnsredir_network - Network for hpc_watcher to contact dnsredir instance
-             * 
-             */
-            hpcapi.prototype.Hpc_Service_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/hpcservices/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters['kind'] !== undefined) {
-                    form['kind'] = parameters['kind'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['versionNumber'] !== undefined) {
-                    form['versionNumber'] = parameters['versionNumber'];
-                }
-
-                if (parameters['published'] !== undefined) {
-                    form['published'] = parameters['published'];
-                }
-
-                if (parameters['view_url'] !== undefined) {
-                    form['view_url'] = parameters['view_url'];
-                }
-
-                if (parameters['icon_url'] !== undefined) {
-                    form['icon_url'] = parameters['icon_url'];
-                }
-
-                if (parameters['public_key'] !== undefined) {
-                    form['public_key'] = parameters['public_key'];
-                }
-
-                if (parameters['service_specific_id'] !== undefined) {
-                    form['service_specific_id'] = parameters['service_specific_id'];
-                }
-
-                if (parameters['service_specific_attribute'] !== undefined) {
-                    form['service_specific_attribute'] = parameters['service_specific_attribute'];
-                }
-
-                if (parameters['cmi_hostname'] !== undefined) {
-                    form['cmi_hostname'] = parameters['cmi_hostname'];
-                }
-
-                if (parameters['hpc_port80'] !== undefined) {
-                    form['hpc_port80'] = parameters['hpc_port80'];
-                }
-
-                if (parameters['watcher_hpc_network'] !== undefined) {
-                    form['watcher_hpc_network'] = parameters['watcher_hpc_network'];
-                }
-
-                if (parameters['watcher_dnsdemux_network'] !== undefined) {
-                    form['watcher_dnsdemux_network'] = parameters['watcher_dnsdemux_network'];
-                }
-
-                if (parameters['watcher_dnsredir_network'] !== undefined) {
-                    form['watcher_dnsredir_network'] = parameters['watcher_dnsredir_network'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Hpc_Service_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            hpcapi.prototype.Hpc_Service_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/hpcservices/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Origin_Server_List_GET
-             * 
-             */
-            hpcapi.prototype.Origin_Server_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/originservers/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Origin_Server_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {integer} origin_server_id - 
-             * @param {string} url - 
-             * @param {string} contentProvider - 
-             * @param {boolean} authenticated - Status for this Site
-             * @param {boolean} enabled - Status for this Site
-             * @param {choice} protocol - 
-             * @param {boolean} redirects - Indicates whether Origin Server redirects should be used for this Origin Server
-             * @param {string} description - 
-             * 
-             */
-            hpcapi.prototype.Origin_Server_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/originservers/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['origin_server_id'] !== undefined) {
-                    form['origin_server_id'] = parameters['origin_server_id'];
-                }
-
-                if (parameters['url'] !== undefined) {
-                    form['url'] = parameters['url'];
-                }
-
-                if (parameters['url'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url'));
-                    return deferred.promise;
-                }
-
-                if (parameters['contentProvider'] !== undefined) {
-                    form['contentProvider'] = parameters['contentProvider'];
-                }
-
-                if (parameters['contentProvider'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: contentProvider'));
-                    return deferred.promise;
-                }
-
-                if (parameters['authenticated'] !== undefined) {
-                    form['authenticated'] = parameters['authenticated'];
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters['protocol'] !== undefined) {
-                    form['protocol'] = parameters['protocol'];
-                }
-
-                if (parameters['protocol'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: protocol'));
-                    return deferred.promise;
-                }
-
-                if (parameters['redirects'] !== undefined) {
-                    form['redirects'] = parameters['redirects'];
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Origin_Server_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            hpcapi.prototype.Origin_Server_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/originservers/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Origin_Server_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {integer} origin_server_id - 
-             * @param {string} url - 
-             * @param {string} contentProvider - 
-             * @param {boolean} authenticated - Status for this Site
-             * @param {boolean} enabled - Status for this Site
-             * @param {choice} protocol - 
-             * @param {boolean} redirects - Indicates whether Origin Server redirects should be used for this Origin Server
-             * @param {string} description - 
-             * 
-             */
-            hpcapi.prototype.Origin_Server_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/originservers/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['origin_server_id'] !== undefined) {
-                    form['origin_server_id'] = parameters['origin_server_id'];
-                }
-
-                if (parameters['url'] !== undefined) {
-                    form['url'] = parameters['url'];
-                }
-
-                if (parameters['url'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url'));
-                    return deferred.promise;
-                }
-
-                if (parameters['contentProvider'] !== undefined) {
-                    form['contentProvider'] = parameters['contentProvider'];
-                }
-
-                if (parameters['contentProvider'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: contentProvider'));
-                    return deferred.promise;
-                }
-
-                if (parameters['authenticated'] !== undefined) {
-                    form['authenticated'] = parameters['authenticated'];
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters['protocol'] !== undefined) {
-                    form['protocol'] = parameters['protocol'];
-                }
-
-                if (parameters['protocol'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: protocol'));
-                    return deferred.promise;
-                }
-
-                if (parameters['redirects'] !== undefined) {
-                    form['redirects'] = parameters['redirects'];
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Origin_Server_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {integer} origin_server_id - 
-             * @param {string} url - 
-             * @param {string} contentProvider - 
-             * @param {boolean} authenticated - Status for this Site
-             * @param {boolean} enabled - Status for this Site
-             * @param {choice} protocol - 
-             * @param {boolean} redirects - Indicates whether Origin Server redirects should be used for this Origin Server
-             * @param {string} description - 
-             * 
-             */
-            hpcapi.prototype.Origin_Server_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/originservers/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['origin_server_id'] !== undefined) {
-                    form['origin_server_id'] = parameters['origin_server_id'];
-                }
-
-                if (parameters['url'] !== undefined) {
-                    form['url'] = parameters['url'];
-                }
-
-                if (parameters['contentProvider'] !== undefined) {
-                    form['contentProvider'] = parameters['contentProvider'];
-                }
-
-                if (parameters['authenticated'] !== undefined) {
-                    form['authenticated'] = parameters['authenticated'];
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters['protocol'] !== undefined) {
-                    form['protocol'] = parameters['protocol'];
-                }
-
-                if (parameters['redirects'] !== undefined) {
-                    form['redirects'] = parameters['redirects'];
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Origin_Server_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            hpcapi.prototype.Origin_Server_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/originservers/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Cdn_Prefix_List_GET
-             * 
-             */
-            hpcapi.prototype.Cdn_Prefix_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/cdnprefixs/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Cdn_Prefix_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {integer} cdn_prefix_id - 
-             * @param {string} prefix - Registered Prefix for Domain
-             * @param {string} contentProvider - 
-             * @param {string} description - Description of Content Provider
-             * @param {string} defaultOriginServer - 
-             * @param {boolean} enabled - 
-             * 
-             */
-            hpcapi.prototype.Cdn_Prefix_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/cdnprefixs/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['cdn_prefix_id'] !== undefined) {
-                    form['cdn_prefix_id'] = parameters['cdn_prefix_id'];
-                }
-
-                if (parameters['prefix'] !== undefined) {
-                    form['prefix'] = parameters['prefix'];
-                }
-
-                if (parameters['prefix'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: prefix'));
-                    return deferred.promise;
-                }
-
-                if (parameters['contentProvider'] !== undefined) {
-                    form['contentProvider'] = parameters['contentProvider'];
-                }
-
-                if (parameters['contentProvider'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: contentProvider'));
-                    return deferred.promise;
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['defaultOriginServer'] !== undefined) {
-                    form['defaultOriginServer'] = parameters['defaultOriginServer'];
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Cdn_Prefix_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            hpcapi.prototype.Cdn_Prefix_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/cdnprefixs/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Cdn_Prefix_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {integer} cdn_prefix_id - 
-             * @param {string} prefix - Registered Prefix for Domain
-             * @param {string} contentProvider - 
-             * @param {string} description - Description of Content Provider
-             * @param {string} defaultOriginServer - 
-             * @param {boolean} enabled - 
-             * 
-             */
-            hpcapi.prototype.Cdn_Prefix_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/cdnprefixs/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['cdn_prefix_id'] !== undefined) {
-                    form['cdn_prefix_id'] = parameters['cdn_prefix_id'];
-                }
-
-                if (parameters['prefix'] !== undefined) {
-                    form['prefix'] = parameters['prefix'];
-                }
-
-                if (parameters['prefix'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: prefix'));
-                    return deferred.promise;
-                }
-
-                if (parameters['contentProvider'] !== undefined) {
-                    form['contentProvider'] = parameters['contentProvider'];
-                }
-
-                if (parameters['contentProvider'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: contentProvider'));
-                    return deferred.promise;
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['defaultOriginServer'] !== undefined) {
-                    form['defaultOriginServer'] = parameters['defaultOriginServer'];
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Cdn_Prefix_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {integer} cdn_prefix_id - 
-             * @param {string} prefix - Registered Prefix for Domain
-             * @param {string} contentProvider - 
-             * @param {string} description - Description of Content Provider
-             * @param {string} defaultOriginServer - 
-             * @param {boolean} enabled - 
-             * 
-             */
-            hpcapi.prototype.Cdn_Prefix_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/cdnprefixs/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['cdn_prefix_id'] !== undefined) {
-                    form['cdn_prefix_id'] = parameters['cdn_prefix_id'];
-                }
-
-                if (parameters['prefix'] !== undefined) {
-                    form['prefix'] = parameters['prefix'];
-                }
-
-                if (parameters['contentProvider'] !== undefined) {
-                    form['contentProvider'] = parameters['contentProvider'];
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['defaultOriginServer'] !== undefined) {
-                    form['defaultOriginServer'] = parameters['defaultOriginServer'];
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Cdn_Prefix_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            hpcapi.prototype.Cdn_Prefix_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/cdnprefixs/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Service_Provider_List_GET
-             * 
-             */
-            hpcapi.prototype.Service_Provider_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/serviceproviders/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Service_Provider_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} hpcService - 
-             * @param {integer} service_provider_id - 
-             * @param {string} name - Service Provider Name
-             * @param {string} description - Description of Service Provider
-             * @param {boolean} enabled - 
-             * 
-             */
-            hpcapi.prototype.Service_Provider_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/serviceproviders/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['hpcService'] !== undefined) {
-                    form['hpcService'] = parameters['hpcService'];
-                }
-
-                if (parameters['hpcService'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: hpcService'));
-                    return deferred.promise;
-                }
-
-                if (parameters['service_provider_id'] !== undefined) {
-                    form['service_provider_id'] = parameters['service_provider_id'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Service_Provider_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            hpcapi.prototype.Service_Provider_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/serviceproviders/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Service_Provider_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} hpcService - 
-             * @param {integer} service_provider_id - 
-             * @param {string} name - Service Provider Name
-             * @param {string} description - Description of Service Provider
-             * @param {boolean} enabled - 
-             * 
-             */
-            hpcapi.prototype.Service_Provider_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/serviceproviders/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['hpcService'] !== undefined) {
-                    form['hpcService'] = parameters['hpcService'];
-                }
-
-                if (parameters['hpcService'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: hpcService'));
-                    return deferred.promise;
-                }
-
-                if (parameters['service_provider_id'] !== undefined) {
-                    form['service_provider_id'] = parameters['service_provider_id'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Service_Provider_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} hpcService - 
-             * @param {integer} service_provider_id - 
-             * @param {string} name - Service Provider Name
-             * @param {string} description - Description of Service Provider
-             * @param {boolean} enabled - 
-             * 
-             */
-            hpcapi.prototype.Service_Provider_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/serviceproviders/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['hpcService'] !== undefined) {
-                    form['hpcService'] = parameters['hpcService'];
-                }
-
-                if (parameters['service_provider_id'] !== undefined) {
-                    form['service_provider_id'] = parameters['service_provider_id'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Service_Provider_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            hpcapi.prototype.Service_Provider_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/serviceproviders/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Content_Provider_List_GET
-             * 
-             */
-            hpcapi.prototype.Content_Provider_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/contentproviders/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Content_Provider_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {integer} content_provider_id - 
-             * @param {string} name - 
-             * @param {boolean} enabled - 
-             * @param {string} description - Description of Content Provider
-             * @param {string} serviceProvider - 
-             * 
-             */
-            hpcapi.prototype.Content_Provider_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/contentproviders/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['content_provider_id'] !== undefined) {
-                    form['content_provider_id'] = parameters['content_provider_id'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['serviceProvider'] !== undefined) {
-                    form['serviceProvider'] = parameters['serviceProvider'];
-                }
-
-                if (parameters['serviceProvider'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: serviceProvider'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Content_Provider_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            hpcapi.prototype.Content_Provider_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/contentproviders/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Content_Provider_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {integer} content_provider_id - 
-             * @param {string} name - 
-             * @param {boolean} enabled - 
-             * @param {string} description - Description of Content Provider
-             * @param {string} serviceProvider - 
-             * 
-             */
-            hpcapi.prototype.Content_Provider_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/contentproviders/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['content_provider_id'] !== undefined) {
-                    form['content_provider_id'] = parameters['content_provider_id'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['serviceProvider'] !== undefined) {
-                    form['serviceProvider'] = parameters['serviceProvider'];
-                }
-
-                if (parameters['serviceProvider'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: serviceProvider'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Content_Provider_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {integer} content_provider_id - 
-             * @param {string} name - 
-             * @param {boolean} enabled - 
-             * @param {string} description - Description of Content Provider
-             * @param {string} serviceProvider - 
-             * 
-             */
-            hpcapi.prototype.Content_Provider_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/contentproviders/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['content_provider_id'] !== undefined) {
-                    form['content_provider_id'] = parameters['content_provider_id'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['serviceProvider'] !== undefined) {
-                    form['serviceProvider'] = parameters['serviceProvider'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Content_Provider_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            hpcapi.prototype.Content_Provider_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/contentproviders/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Access_Map_List_GET
-             * 
-             */
-            hpcapi.prototype.Access_Map_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/accessmaps/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Access_Map_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} contentProvider - 
-             * @param {string} name - Name of the Access Map
-             * @param {string} description - 
-             * @param {string} map - specifies which client requests are allowed
-             * 
-             */
-            hpcapi.prototype.Access_Map_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/accessmaps/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['contentProvider'] !== undefined) {
-                    form['contentProvider'] = parameters['contentProvider'];
-                }
-
-                if (parameters['contentProvider'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: contentProvider'));
-                    return deferred.promise;
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['map'] !== undefined) {
-                    form['map'] = parameters['map'];
-                }
-
-                if (parameters['map'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: map'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Access_Map_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            hpcapi.prototype.Access_Map_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/accessmaps/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Access_Map_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} contentProvider - 
-             * @param {string} name - Name of the Access Map
-             * @param {string} description - 
-             * @param {string} map - specifies which client requests are allowed
-             * 
-             */
-            hpcapi.prototype.Access_Map_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/accessmaps/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['contentProvider'] !== undefined) {
-                    form['contentProvider'] = parameters['contentProvider'];
-                }
-
-                if (parameters['contentProvider'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: contentProvider'));
-                    return deferred.promise;
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['map'] !== undefined) {
-                    form['map'] = parameters['map'];
-                }
-
-                if (parameters['map'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: map'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Access_Map_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} contentProvider - 
-             * @param {string} name - Name of the Access Map
-             * @param {string} description - 
-             * @param {string} map - specifies which client requests are allowed
-             * 
-             */
-            hpcapi.prototype.Access_Map_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/accessmaps/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['contentProvider'] !== undefined) {
-                    form['contentProvider'] = parameters['contentProvider'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['map'] !== undefined) {
-                    form['map'] = parameters['map'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Access_Map_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            hpcapi.prototype.Access_Map_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/accessmaps/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Site_Map_List_GET
-             * 
-             */
-            hpcapi.prototype.Site_Map_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/sitemaps/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Site_Map_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} contentProvider - 
-             * @param {string} serviceProvider - 
-             * @param {string} cdnPrefix - 
-             * @param {string} hpcService - 
-             * @param {string} name - Name of the Site Map
-             * @param {string} description - 
-             * @param {string} map - specifies how to map requests to hpc instances
-             * @param {integer} map_id - 
-             * 
-             */
-            hpcapi.prototype.Site_Map_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/sitemaps/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['contentProvider'] !== undefined) {
-                    form['contentProvider'] = parameters['contentProvider'];
-                }
-
-                if (parameters['serviceProvider'] !== undefined) {
-                    form['serviceProvider'] = parameters['serviceProvider'];
-                }
-
-                if (parameters['cdnPrefix'] !== undefined) {
-                    form['cdnPrefix'] = parameters['cdnPrefix'];
-                }
-
-                if (parameters['hpcService'] !== undefined) {
-                    form['hpcService'] = parameters['hpcService'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['map'] !== undefined) {
-                    form['map'] = parameters['map'];
-                }
-
-                if (parameters['map'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: map'));
-                    return deferred.promise;
-                }
-
-                if (parameters['map_id'] !== undefined) {
-                    form['map_id'] = parameters['map_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Site_Map_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            hpcapi.prototype.Site_Map_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/sitemaps/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Site_Map_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} contentProvider - 
-             * @param {string} serviceProvider - 
-             * @param {string} cdnPrefix - 
-             * @param {string} hpcService - 
-             * @param {string} name - Name of the Site Map
-             * @param {string} description - 
-             * @param {string} map - specifies how to map requests to hpc instances
-             * @param {integer} map_id - 
-             * 
-             */
-            hpcapi.prototype.Site_Map_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/sitemaps/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['contentProvider'] !== undefined) {
-                    form['contentProvider'] = parameters['contentProvider'];
-                }
-
-                if (parameters['serviceProvider'] !== undefined) {
-                    form['serviceProvider'] = parameters['serviceProvider'];
-                }
-
-                if (parameters['cdnPrefix'] !== undefined) {
-                    form['cdnPrefix'] = parameters['cdnPrefix'];
-                }
-
-                if (parameters['hpcService'] !== undefined) {
-                    form['hpcService'] = parameters['hpcService'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['map'] !== undefined) {
-                    form['map'] = parameters['map'];
-                }
-
-                if (parameters['map'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: map'));
-                    return deferred.promise;
-                }
-
-                if (parameters['map_id'] !== undefined) {
-                    form['map_id'] = parameters['map_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Site_Map_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} contentProvider - 
-             * @param {string} serviceProvider - 
-             * @param {string} cdnPrefix - 
-             * @param {string} hpcService - 
-             * @param {string} name - Name of the Site Map
-             * @param {string} description - 
-             * @param {string} map - specifies how to map requests to hpc instances
-             * @param {integer} map_id - 
-             * 
-             */
-            hpcapi.prototype.Site_Map_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/sitemaps/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['contentProvider'] !== undefined) {
-                    form['contentProvider'] = parameters['contentProvider'];
-                }
-
-                if (parameters['serviceProvider'] !== undefined) {
-                    form['serviceProvider'] = parameters['serviceProvider'];
-                }
-
-                if (parameters['cdnPrefix'] !== undefined) {
-                    form['cdnPrefix'] = parameters['cdnPrefix'];
-                }
-
-                if (parameters['hpcService'] !== undefined) {
-                    form['hpcService'] = parameters['hpcService'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['map'] !== undefined) {
-                    form['map'] = parameters['map'];
-                }
-
-                if (parameters['map_id'] !== undefined) {
-                    form['map_id'] = parameters['map_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name hpcapi#Site_Map_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            hpcapi.prototype.Site_Map_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/hpcapi/sitemaps/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = hpcapi.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-
-            return hpcapi;
-        })();
-
-        return hpcapi;
-    }]);
\ No newline at end of file
diff --git a/xos/core/xoslib/ngXosLib/api/ng-xos.js b/xos/core/xoslib/ngXosLib/api/ng-xos.js
deleted file mode 100644
index 2f62f9e..0000000
--- a/xos/core/xoslib/ngXosLib/api/ng-xos.js
+++ /dev/null
@@ -1,39960 +0,0 @@
-/*jshint -W069 */
-/*global angular:false */
-angular.module('xos.xos', [])
-    .factory('xos', ['$q', '$http', '$rootScope', function($q, $http, $rootScope) {
-        'use strict';
-
-        /**
-         * 
-         * @class xos
-         * @param {(string|object)} [domainOrOptions] - The project domain or options object. If object, see the object's optional properties.
-         * @param {string} [domainOrOptions.domain] - The project domain
-         * @param {string} [domainOrOptions.cache] - An angularjs cache implementation
-         * @param {object} [domainOrOptions.token] - auth token - object with value property and optional headerOrQueryName and isQuery properties
-         * @param {string} [cache] - An angularjs cache implementation
-         */
-        var xos = (function() {
-            function xos(options, cache) {
-                var domain = (typeof options === 'object') ? options.domain : options;
-                this.domain = typeof(domain) === 'string' ? domain : 'http://localhost:9999';
-                if (this.domain.length === 0) {
-                    throw new Error('Domain parameter must be specified as a string.');
-                }
-                cache = cache || ((typeof options === 'object') ? options.cache : cache);
-                this.cache = cache;
-            }
-
-            xos.prototype.$on = function($scope, path, handler) {
-                var url = domain + path;
-                $scope.$on(url, function() {
-                    handler();
-                });
-                return this;
-            };
-
-            xos.prototype.$broadcast = function(path) {
-                var url = domain + path;
-                //cache.remove(url);
-                $rootScope.$broadcast(url);
-                return this;
-            };
-
-            xos.transformRequest = function(obj) {
-                var str = [];
-                for (var p in obj) {
-                    var val = obj[p];
-                    if (angular.isArray(val)) {
-                        val.forEach(function(val) {
-                            str.push(encodeURIComponent(p) + "=" + encodeURIComponent(val));
-                        });
-                    } else {
-                        str.push(encodeURIComponent(p) + "=" + encodeURIComponent(val));
-                    }
-                }
-                return str.join("&");
-            };
-
-            /**
-             * 
-             * @method
-             * @name xos#Api_Root_GET
-             * 
-             */
-            xos.prototype.Api_Root_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Site_Role_List_GET
-             * 
-             */
-            xos.prototype.Site_Role_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/site_roles/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Site_Role_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {choice} role - 
-             * 
-             */
-            xos.prototype.Site_Role_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/site_roles/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['role'] !== undefined) {
-                    form['role'] = parameters['role'];
-                }
-
-                if (parameters['role'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: role'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Site_Role_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Site_Role_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/site_roles/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Site_Role_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {choice} role - 
-             * 
-             */
-            xos.prototype.Site_Role_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/site_roles/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['role'] !== undefined) {
-                    form['role'] = parameters['role'];
-                }
-
-                if (parameters['role'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: role'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Site_Role_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {choice} role - 
-             * 
-             */
-            xos.prototype.Site_Role_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/site_roles/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['role'] !== undefined) {
-                    form['role'] = parameters['role'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Site_Role_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Site_Role_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/site_roles/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Service_Attribute_List_GET
-             * 
-             */
-            xos.prototype.Service_Attribute_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/serviceattributes/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Service_Attribute_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - Attribute Name
-             * @param {string} value - Attribute Value
-             * @param {string} service - The Service this attribute is associated with
-             * 
-             */
-            xos.prototype.Service_Attribute_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/serviceattributes/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['value'] !== undefined) {
-                    form['value'] = parameters['value'];
-                }
-
-                if (parameters['value'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: value'));
-                    return deferred.promise;
-                }
-
-                if (parameters['service'] !== undefined) {
-                    form['service'] = parameters['service'];
-                }
-
-                if (parameters['service'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: service'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Service_Attribute_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Service_Attribute_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/serviceattributes/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Service_Attribute_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - Attribute Name
-             * @param {string} value - Attribute Value
-             * @param {string} service - The Service this attribute is associated with
-             * 
-             */
-            xos.prototype.Service_Attribute_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/serviceattributes/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['value'] !== undefined) {
-                    form['value'] = parameters['value'];
-                }
-
-                if (parameters['value'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: value'));
-                    return deferred.promise;
-                }
-
-                if (parameters['service'] !== undefined) {
-                    form['service'] = parameters['service'];
-                }
-
-                if (parameters['service'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: service'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Service_Attribute_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - Attribute Name
-             * @param {string} value - Attribute Value
-             * @param {string} service - The Service this attribute is associated with
-             * 
-             */
-            xos.prototype.Service_Attribute_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/serviceattributes/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['value'] !== undefined) {
-                    form['value'] = parameters['value'];
-                }
-
-                if (parameters['service'] !== undefined) {
-                    form['service'] = parameters['service'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Service_Attribute_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Service_Attribute_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/serviceattributes/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Images_List_GET
-             * 
-             */
-            xos.prototype.Controller_Images_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllerimages/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Images_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} image - 
-             * @param {string} controller - 
-             * @param {string} glance_image_id - Glance image id
-             * 
-             */
-            xos.prototype.Controller_Images_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllerimages/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['image'] !== undefined) {
-                    form['image'] = parameters['image'];
-                }
-
-                if (parameters['image'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: image'));
-                    return deferred.promise;
-                }
-
-                if (parameters['controller'] !== undefined) {
-                    form['controller'] = parameters['controller'];
-                }
-
-                if (parameters['controller'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: controller'));
-                    return deferred.promise;
-                }
-
-                if (parameters['glance_image_id'] !== undefined) {
-                    form['glance_image_id'] = parameters['glance_image_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Images_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Controller_Images_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllerimages/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Images_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} image - 
-             * @param {string} controller - 
-             * @param {string} glance_image_id - Glance image id
-             * 
-             */
-            xos.prototype.Controller_Images_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllerimages/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['image'] !== undefined) {
-                    form['image'] = parameters['image'];
-                }
-
-                if (parameters['image'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: image'));
-                    return deferred.promise;
-                }
-
-                if (parameters['controller'] !== undefined) {
-                    form['controller'] = parameters['controller'];
-                }
-
-                if (parameters['controller'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: controller'));
-                    return deferred.promise;
-                }
-
-                if (parameters['glance_image_id'] !== undefined) {
-                    form['glance_image_id'] = parameters['glance_image_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Images_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} image - 
-             * @param {string} controller - 
-             * @param {string} glance_image_id - Glance image id
-             * 
-             */
-            xos.prototype.Controller_Images_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllerimages/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['image'] !== undefined) {
-                    form['image'] = parameters['image'];
-                }
-
-                if (parameters['controller'] !== undefined) {
-                    form['controller'] = parameters['controller'];
-                }
-
-                if (parameters['glance_image_id'] !== undefined) {
-                    form['glance_image_id'] = parameters['glance_image_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Images_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Controller_Images_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllerimages/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Site_Privilege_List_GET
-             * 
-             */
-            xos.prototype.Controller_Site_Privilege_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllersiteprivileges/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Site_Privilege_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} controller - 
-             * @param {string} site_privilege - 
-             * @param {string} role_id - Keystone id
-             * 
-             */
-            xos.prototype.Controller_Site_Privilege_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllersiteprivileges/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['controller'] !== undefined) {
-                    form['controller'] = parameters['controller'];
-                }
-
-                if (parameters['controller'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: controller'));
-                    return deferred.promise;
-                }
-
-                if (parameters['site_privilege'] !== undefined) {
-                    form['site_privilege'] = parameters['site_privilege'];
-                }
-
-                if (parameters['site_privilege'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: site_privilege'));
-                    return deferred.promise;
-                }
-
-                if (parameters['role_id'] !== undefined) {
-                    form['role_id'] = parameters['role_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Site_Privilege_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Controller_Site_Privilege_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllersiteprivileges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Site_Privilege_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} controller - 
-             * @param {string} site_privilege - 
-             * @param {string} role_id - Keystone id
-             * 
-             */
-            xos.prototype.Controller_Site_Privilege_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllersiteprivileges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['controller'] !== undefined) {
-                    form['controller'] = parameters['controller'];
-                }
-
-                if (parameters['controller'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: controller'));
-                    return deferred.promise;
-                }
-
-                if (parameters['site_privilege'] !== undefined) {
-                    form['site_privilege'] = parameters['site_privilege'];
-                }
-
-                if (parameters['site_privilege'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: site_privilege'));
-                    return deferred.promise;
-                }
-
-                if (parameters['role_id'] !== undefined) {
-                    form['role_id'] = parameters['role_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Site_Privilege_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} controller - 
-             * @param {string} site_privilege - 
-             * @param {string} role_id - Keystone id
-             * 
-             */
-            xos.prototype.Controller_Site_Privilege_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllersiteprivileges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['controller'] !== undefined) {
-                    form['controller'] = parameters['controller'];
-                }
-
-                if (parameters['site_privilege'] !== undefined) {
-                    form['site_privilege'] = parameters['site_privilege'];
-                }
-
-                if (parameters['role_id'] !== undefined) {
-                    form['role_id'] = parameters['role_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Site_Privilege_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Controller_Site_Privilege_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllersiteprivileges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Image_List_GET
-             * 
-             */
-            xos.prototype.Image_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/images/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Image_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - 
-             * @param {string} disk_format - 
-             * @param {string} container_format - 
-             * @param {string} path - Path to image on local disk
-             * 
-             */
-            xos.prototype.Image_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/images/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['disk_format'] !== undefined) {
-                    form['disk_format'] = parameters['disk_format'];
-                }
-
-                if (parameters['disk_format'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: disk_format'));
-                    return deferred.promise;
-                }
-
-                if (parameters['container_format'] !== undefined) {
-                    form['container_format'] = parameters['container_format'];
-                }
-
-                if (parameters['container_format'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: container_format'));
-                    return deferred.promise;
-                }
-
-                if (parameters['path'] !== undefined) {
-                    form['path'] = parameters['path'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Image_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Image_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/images/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Image_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - 
-             * @param {string} disk_format - 
-             * @param {string} container_format - 
-             * @param {string} path - Path to image on local disk
-             * 
-             */
-            xos.prototype.Image_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/images/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['disk_format'] !== undefined) {
-                    form['disk_format'] = parameters['disk_format'];
-                }
-
-                if (parameters['disk_format'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: disk_format'));
-                    return deferred.promise;
-                }
-
-                if (parameters['container_format'] !== undefined) {
-                    form['container_format'] = parameters['container_format'];
-                }
-
-                if (parameters['container_format'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: container_format'));
-                    return deferred.promise;
-                }
-
-                if (parameters['path'] !== undefined) {
-                    form['path'] = parameters['path'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Image_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - 
-             * @param {string} disk_format - 
-             * @param {string} container_format - 
-             * @param {string} path - Path to image on local disk
-             * 
-             */
-            xos.prototype.Image_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/images/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['disk_format'] !== undefined) {
-                    form['disk_format'] = parameters['disk_format'];
-                }
-
-                if (parameters['container_format'] !== undefined) {
-                    form['container_format'] = parameters['container_format'];
-                }
-
-                if (parameters['path'] !== undefined) {
-                    form['path'] = parameters['path'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Image_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Image_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/images/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Network_Parameter_List_GET
-             * 
-             */
-            xos.prototype.Network_Parameter_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/networkparameters/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Network_Parameter_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} parameter - The type of the parameter
-             * @param {string} value - The value of this parameter
-             * @param {string} content_type - 
-             * @param {integer} object_id - 
-             * 
-             */
-            xos.prototype.Network_Parameter_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/networkparameters/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['parameter'] !== undefined) {
-                    form['parameter'] = parameters['parameter'];
-                }
-
-                if (parameters['parameter'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: parameter'));
-                    return deferred.promise;
-                }
-
-                if (parameters['value'] !== undefined) {
-                    form['value'] = parameters['value'];
-                }
-
-                if (parameters['value'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: value'));
-                    return deferred.promise;
-                }
-
-                if (parameters['content_type'] !== undefined) {
-                    form['content_type'] = parameters['content_type'];
-                }
-
-                if (parameters['content_type'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: content_type'));
-                    return deferred.promise;
-                }
-
-                if (parameters['object_id'] !== undefined) {
-                    form['object_id'] = parameters['object_id'];
-                }
-
-                if (parameters['object_id'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: object_id'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Network_Parameter_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Network_Parameter_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/networkparameters/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Network_Parameter_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} parameter - The type of the parameter
-             * @param {string} value - The value of this parameter
-             * @param {string} content_type - 
-             * @param {integer} object_id - 
-             * 
-             */
-            xos.prototype.Network_Parameter_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/networkparameters/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['parameter'] !== undefined) {
-                    form['parameter'] = parameters['parameter'];
-                }
-
-                if (parameters['parameter'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: parameter'));
-                    return deferred.promise;
-                }
-
-                if (parameters['value'] !== undefined) {
-                    form['value'] = parameters['value'];
-                }
-
-                if (parameters['value'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: value'));
-                    return deferred.promise;
-                }
-
-                if (parameters['content_type'] !== undefined) {
-                    form['content_type'] = parameters['content_type'];
-                }
-
-                if (parameters['content_type'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: content_type'));
-                    return deferred.promise;
-                }
-
-                if (parameters['object_id'] !== undefined) {
-                    form['object_id'] = parameters['object_id'];
-                }
-
-                if (parameters['object_id'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: object_id'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Network_Parameter_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} parameter - The type of the parameter
-             * @param {string} value - The value of this parameter
-             * @param {string} content_type - 
-             * @param {integer} object_id - 
-             * 
-             */
-            xos.prototype.Network_Parameter_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/networkparameters/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['parameter'] !== undefined) {
-                    form['parameter'] = parameters['parameter'];
-                }
-
-                if (parameters['value'] !== undefined) {
-                    form['value'] = parameters['value'];
-                }
-
-                if (parameters['content_type'] !== undefined) {
-                    form['content_type'] = parameters['content_type'];
-                }
-
-                if (parameters['object_id'] !== undefined) {
-                    form['object_id'] = parameters['object_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Network_Parameter_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Network_Parameter_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/networkparameters/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Site_List_GET
-             * 
-             */
-            xos.prototype.Site_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/sites/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Site_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - Name for this Site
-             * @param {string} site_url - Site's Home URL Page
-             * @param {boolean} enabled - Status for this Site
-             * @param {boolean} hosts_nodes - Indicates whether or not the site host nodes
-             * @param {boolean} hosts_users - Indicates whether or not the site manages user accounts
-             * @param {string} location - 
-             * @param {number} longitude - 
-             * @param {number} latitude - 
-             * @param {string} login_base - Prefix for Slices associated with this Site
-             * @param {boolean} is_public - Indicates the visibility of this site to other members
-             * @param {string} abbreviated_name - 
-             * 
-             */
-            xos.prototype.Site_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/sites/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['site_url'] !== undefined) {
-                    form['site_url'] = parameters['site_url'];
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters['hosts_nodes'] !== undefined) {
-                    form['hosts_nodes'] = parameters['hosts_nodes'];
-                }
-
-                if (parameters['hosts_users'] !== undefined) {
-                    form['hosts_users'] = parameters['hosts_users'];
-                }
-
-                if (parameters['location'] !== undefined) {
-                    form['location'] = parameters['location'];
-                }
-
-                if (parameters['location'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: location'));
-                    return deferred.promise;
-                }
-
-                if (parameters['longitude'] !== undefined) {
-                    form['longitude'] = parameters['longitude'];
-                }
-
-                if (parameters['latitude'] !== undefined) {
-                    form['latitude'] = parameters['latitude'];
-                }
-
-                if (parameters['login_base'] !== undefined) {
-                    form['login_base'] = parameters['login_base'];
-                }
-
-                if (parameters['login_base'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: login_base'));
-                    return deferred.promise;
-                }
-
-                if (parameters['is_public'] !== undefined) {
-                    form['is_public'] = parameters['is_public'];
-                }
-
-                if (parameters['abbreviated_name'] !== undefined) {
-                    form['abbreviated_name'] = parameters['abbreviated_name'];
-                }
-
-                if (parameters['abbreviated_name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: abbreviated_name'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Site_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Site_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/sites/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Site_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - Name for this Site
-             * @param {string} site_url - Site's Home URL Page
-             * @param {boolean} enabled - Status for this Site
-             * @param {boolean} hosts_nodes - Indicates whether or not the site host nodes
-             * @param {boolean} hosts_users - Indicates whether or not the site manages user accounts
-             * @param {string} location - 
-             * @param {number} longitude - 
-             * @param {number} latitude - 
-             * @param {string} login_base - Prefix for Slices associated with this Site
-             * @param {boolean} is_public - Indicates the visibility of this site to other members
-             * @param {string} abbreviated_name - 
-             * 
-             */
-            xos.prototype.Site_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/sites/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['site_url'] !== undefined) {
-                    form['site_url'] = parameters['site_url'];
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters['hosts_nodes'] !== undefined) {
-                    form['hosts_nodes'] = parameters['hosts_nodes'];
-                }
-
-                if (parameters['hosts_users'] !== undefined) {
-                    form['hosts_users'] = parameters['hosts_users'];
-                }
-
-                if (parameters['location'] !== undefined) {
-                    form['location'] = parameters['location'];
-                }
-
-                if (parameters['location'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: location'));
-                    return deferred.promise;
-                }
-
-                if (parameters['longitude'] !== undefined) {
-                    form['longitude'] = parameters['longitude'];
-                }
-
-                if (parameters['latitude'] !== undefined) {
-                    form['latitude'] = parameters['latitude'];
-                }
-
-                if (parameters['login_base'] !== undefined) {
-                    form['login_base'] = parameters['login_base'];
-                }
-
-                if (parameters['login_base'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: login_base'));
-                    return deferred.promise;
-                }
-
-                if (parameters['is_public'] !== undefined) {
-                    form['is_public'] = parameters['is_public'];
-                }
-
-                if (parameters['abbreviated_name'] !== undefined) {
-                    form['abbreviated_name'] = parameters['abbreviated_name'];
-                }
-
-                if (parameters['abbreviated_name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: abbreviated_name'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Site_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - Name for this Site
-             * @param {string} site_url - Site's Home URL Page
-             * @param {boolean} enabled - Status for this Site
-             * @param {boolean} hosts_nodes - Indicates whether or not the site host nodes
-             * @param {boolean} hosts_users - Indicates whether or not the site manages user accounts
-             * @param {string} location - 
-             * @param {number} longitude - 
-             * @param {number} latitude - 
-             * @param {string} login_base - Prefix for Slices associated with this Site
-             * @param {boolean} is_public - Indicates the visibility of this site to other members
-             * @param {string} abbreviated_name - 
-             * 
-             */
-            xos.prototype.Site_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/sites/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['site_url'] !== undefined) {
-                    form['site_url'] = parameters['site_url'];
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters['hosts_nodes'] !== undefined) {
-                    form['hosts_nodes'] = parameters['hosts_nodes'];
-                }
-
-                if (parameters['hosts_users'] !== undefined) {
-                    form['hosts_users'] = parameters['hosts_users'];
-                }
-
-                if (parameters['location'] !== undefined) {
-                    form['location'] = parameters['location'];
-                }
-
-                if (parameters['longitude'] !== undefined) {
-                    form['longitude'] = parameters['longitude'];
-                }
-
-                if (parameters['latitude'] !== undefined) {
-                    form['latitude'] = parameters['latitude'];
-                }
-
-                if (parameters['login_base'] !== undefined) {
-                    form['login_base'] = parameters['login_base'];
-                }
-
-                if (parameters['is_public'] !== undefined) {
-                    form['is_public'] = parameters['is_public'];
-                }
-
-                if (parameters['abbreviated_name'] !== undefined) {
-                    form['abbreviated_name'] = parameters['abbreviated_name'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Site_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Site_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/sites/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tenant_Root_Role_List_GET
-             * 
-             */
-            xos.prototype.Tenant_Root_Role_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tenantrootroles/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tenant_Root_Role_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {choice} role - 
-             * 
-             */
-            xos.prototype.Tenant_Root_Role_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tenantrootroles/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['role'] !== undefined) {
-                    form['role'] = parameters['role'];
-                }
-
-                if (parameters['role'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: role'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tenant_Root_Role_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Tenant_Root_Role_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tenantrootroles/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tenant_Root_Role_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {choice} role - 
-             * 
-             */
-            xos.prototype.Tenant_Root_Role_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tenantrootroles/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['role'] !== undefined) {
-                    form['role'] = parameters['role'];
-                }
-
-                if (parameters['role'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: role'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tenant_Root_Role_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {choice} role - 
-             * 
-             */
-            xos.prototype.Tenant_Root_Role_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tenantrootroles/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['role'] !== undefined) {
-                    form['role'] = parameters['role'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tenant_Root_Role_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Tenant_Root_Role_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tenantrootroles/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Slice_Role_List_GET
-             * 
-             */
-            xos.prototype.Slice_Role_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/slice_roles/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Slice_Role_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {choice} role - 
-             * 
-             */
-            xos.prototype.Slice_Role_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/slice_roles/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['role'] !== undefined) {
-                    form['role'] = parameters['role'];
-                }
-
-                if (parameters['role'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: role'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Slice_Role_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Slice_Role_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/slice_roles/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Slice_Role_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {choice} role - 
-             * 
-             */
-            xos.prototype.Slice_Role_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/slice_roles/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['role'] !== undefined) {
-                    form['role'] = parameters['role'];
-                }
-
-                if (parameters['role'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: role'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Slice_Role_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {choice} role - 
-             * 
-             */
-            xos.prototype.Slice_Role_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/slice_roles/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['role'] !== undefined) {
-                    form['role'] = parameters['role'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Slice_Role_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Slice_Role_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/slice_roles/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tag_List_GET
-             * 
-             */
-            xos.prototype.Tag_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tags/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tag_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} service - The Service this Tag is associated with
-             * @param {string} name - The name of this tag
-             * @param {string} value - The value of this tag
-             * @param {string} content_type - 
-             * @param {integer} object_id - 
-             * 
-             */
-            xos.prototype.Tag_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tags/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['service'] !== undefined) {
-                    form['service'] = parameters['service'];
-                }
-
-                if (parameters['service'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: service'));
-                    return deferred.promise;
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['value'] !== undefined) {
-                    form['value'] = parameters['value'];
-                }
-
-                if (parameters['value'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: value'));
-                    return deferred.promise;
-                }
-
-                if (parameters['content_type'] !== undefined) {
-                    form['content_type'] = parameters['content_type'];
-                }
-
-                if (parameters['content_type'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: content_type'));
-                    return deferred.promise;
-                }
-
-                if (parameters['object_id'] !== undefined) {
-                    form['object_id'] = parameters['object_id'];
-                }
-
-                if (parameters['object_id'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: object_id'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tag_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Tag_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tags/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tag_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} service - The Service this Tag is associated with
-             * @param {string} name - The name of this tag
-             * @param {string} value - The value of this tag
-             * @param {string} content_type - 
-             * @param {integer} object_id - 
-             * 
-             */
-            xos.prototype.Tag_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tags/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['service'] !== undefined) {
-                    form['service'] = parameters['service'];
-                }
-
-                if (parameters['service'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: service'));
-                    return deferred.promise;
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['value'] !== undefined) {
-                    form['value'] = parameters['value'];
-                }
-
-                if (parameters['value'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: value'));
-                    return deferred.promise;
-                }
-
-                if (parameters['content_type'] !== undefined) {
-                    form['content_type'] = parameters['content_type'];
-                }
-
-                if (parameters['content_type'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: content_type'));
-                    return deferred.promise;
-                }
-
-                if (parameters['object_id'] !== undefined) {
-                    form['object_id'] = parameters['object_id'];
-                }
-
-                if (parameters['object_id'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: object_id'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tag_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} service - The Service this Tag is associated with
-             * @param {string} name - The name of this tag
-             * @param {string} value - The value of this tag
-             * @param {string} content_type - 
-             * @param {integer} object_id - 
-             * 
-             */
-            xos.prototype.Tag_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tags/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['service'] !== undefined) {
-                    form['service'] = parameters['service'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['value'] !== undefined) {
-                    form['value'] = parameters['value'];
-                }
-
-                if (parameters['content_type'] !== undefined) {
-                    form['content_type'] = parameters['content_type'];
-                }
-
-                if (parameters['object_id'] !== undefined) {
-                    form['object_id'] = parameters['object_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tag_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Tag_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tags/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Invoice_List_GET
-             * 
-             */
-            xos.prototype.Invoice_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/invoices/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Invoice_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} date - 
-             * @param {string} account - 
-             * 
-             */
-            xos.prototype.Invoice_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/invoices/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['date'] !== undefined) {
-                    form['date'] = parameters['date'];
-                }
-
-                if (parameters['date'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: date'));
-                    return deferred.promise;
-                }
-
-                if (parameters['account'] !== undefined) {
-                    form['account'] = parameters['account'];
-                }
-
-                if (parameters['account'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: account'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Invoice_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Invoice_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/invoices/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Invoice_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} date - 
-             * @param {string} account - 
-             * 
-             */
-            xos.prototype.Invoice_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/invoices/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['date'] !== undefined) {
-                    form['date'] = parameters['date'];
-                }
-
-                if (parameters['date'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: date'));
-                    return deferred.promise;
-                }
-
-                if (parameters['account'] !== undefined) {
-                    form['account'] = parameters['account'];
-                }
-
-                if (parameters['account'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: account'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Invoice_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} date - 
-             * @param {string} account - 
-             * 
-             */
-            xos.prototype.Invoice_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/invoices/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['date'] !== undefined) {
-                    form['date'] = parameters['date'];
-                }
-
-                if (parameters['account'] !== undefined) {
-                    form['account'] = parameters['account'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Invoice_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Invoice_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/invoices/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Slice_Privilege_List_GET
-             * 
-             */
-            xos.prototype.Slice_Privilege_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/slice_privileges/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Slice_Privilege_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} user - 
-             * @param {string} slice - 
-             * @param {string} role - 
-             * 
-             */
-            xos.prototype.Slice_Privilege_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/slice_privileges/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['user'] !== undefined) {
-                    form['user'] = parameters['user'];
-                }
-
-                if (parameters['user'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: user'));
-                    return deferred.promise;
-                }
-
-                if (parameters['slice'] !== undefined) {
-                    form['slice'] = parameters['slice'];
-                }
-
-                if (parameters['slice'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: slice'));
-                    return deferred.promise;
-                }
-
-                if (parameters['role'] !== undefined) {
-                    form['role'] = parameters['role'];
-                }
-
-                if (parameters['role'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: role'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Slice_Privilege_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Slice_Privilege_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/slice_privileges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Slice_Privilege_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} user - 
-             * @param {string} slice - 
-             * @param {string} role - 
-             * 
-             */
-            xos.prototype.Slice_Privilege_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/slice_privileges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['user'] !== undefined) {
-                    form['user'] = parameters['user'];
-                }
-
-                if (parameters['user'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: user'));
-                    return deferred.promise;
-                }
-
-                if (parameters['slice'] !== undefined) {
-                    form['slice'] = parameters['slice'];
-                }
-
-                if (parameters['slice'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: slice'));
-                    return deferred.promise;
-                }
-
-                if (parameters['role'] !== undefined) {
-                    form['role'] = parameters['role'];
-                }
-
-                if (parameters['role'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: role'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Slice_Privilege_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} user - 
-             * @param {string} slice - 
-             * @param {string} role - 
-             * 
-             */
-            xos.prototype.Slice_Privilege_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/slice_privileges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['user'] !== undefined) {
-                    form['user'] = parameters['user'];
-                }
-
-                if (parameters['slice'] !== undefined) {
-                    form['slice'] = parameters['slice'];
-                }
-
-                if (parameters['role'] !== undefined) {
-                    form['role'] = parameters['role'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Slice_Privilege_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Slice_Privilege_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/slice_privileges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Flavor_List_GET
-             * 
-             */
-            xos.prototype.Flavor_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/flavors/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Flavor_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - name of this flavor, as displayed to users
-             * @param {string} description - 
-             * @param {string} flavor - flavor string used to configure deployments
-             * @param {integer} order - used to order flavors when displayed in a list
-             * @param {boolean} default - make this a default flavor to use when creating new instances
-             * 
-             */
-            xos.prototype.Flavor_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/flavors/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['flavor'] !== undefined) {
-                    form['flavor'] = parameters['flavor'];
-                }
-
-                if (parameters['flavor'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: flavor'));
-                    return deferred.promise;
-                }
-
-                if (parameters['order'] !== undefined) {
-                    form['order'] = parameters['order'];
-                }
-
-                if (parameters['order'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: order'));
-                    return deferred.promise;
-                }
-
-                if (parameters['default'] !== undefined) {
-                    form['default'] = parameters['default'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Flavor_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Flavor_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/flavors/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Flavor_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - name of this flavor, as displayed to users
-             * @param {string} description - 
-             * @param {string} flavor - flavor string used to configure deployments
-             * @param {integer} order - used to order flavors when displayed in a list
-             * @param {boolean} default - make this a default flavor to use when creating new instances
-             * 
-             */
-            xos.prototype.Flavor_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/flavors/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['flavor'] !== undefined) {
-                    form['flavor'] = parameters['flavor'];
-                }
-
-                if (parameters['flavor'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: flavor'));
-                    return deferred.promise;
-                }
-
-                if (parameters['order'] !== undefined) {
-                    form['order'] = parameters['order'];
-                }
-
-                if (parameters['order'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: order'));
-                    return deferred.promise;
-                }
-
-                if (parameters['default'] !== undefined) {
-                    form['default'] = parameters['default'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Flavor_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - name of this flavor, as displayed to users
-             * @param {string} description - 
-             * @param {string} flavor - flavor string used to configure deployments
-             * @param {integer} order - used to order flavors when displayed in a list
-             * @param {boolean} default - make this a default flavor to use when creating new instances
-             * 
-             */
-            xos.prototype.Flavor_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/flavors/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['flavor'] !== undefined) {
-                    form['flavor'] = parameters['flavor'];
-                }
-
-                if (parameters['order'] !== undefined) {
-                    form['order'] = parameters['order'];
-                }
-
-                if (parameters['default'] !== undefined) {
-                    form['default'] = parameters['default'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Flavor_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Flavor_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/flavors/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Port_List_GET
-             * 
-             */
-            xos.prototype.Port_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/ports/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Port_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} network - 
-             * @param {string} instance - 
-             * @param {string} ip - Instance ip address
-             * @param {string} port_id - Quantum port id
-             * @param {string} mac - MAC address associated with this port
-             * 
-             */
-            xos.prototype.Port_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/ports/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['network'] !== undefined) {
-                    form['network'] = parameters['network'];
-                }
-
-                if (parameters['network'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: network'));
-                    return deferred.promise;
-                }
-
-                if (parameters['instance'] !== undefined) {
-                    form['instance'] = parameters['instance'];
-                }
-
-                if (parameters['ip'] !== undefined) {
-                    form['ip'] = parameters['ip'];
-                }
-
-                if (parameters['port_id'] !== undefined) {
-                    form['port_id'] = parameters['port_id'];
-                }
-
-                if (parameters['mac'] !== undefined) {
-                    form['mac'] = parameters['mac'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Port_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Port_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/ports/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Port_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} network - 
-             * @param {string} instance - 
-             * @param {string} ip - Instance ip address
-             * @param {string} port_id - Quantum port id
-             * @param {string} mac - MAC address associated with this port
-             * 
-             */
-            xos.prototype.Port_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/ports/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['network'] !== undefined) {
-                    form['network'] = parameters['network'];
-                }
-
-                if (parameters['network'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: network'));
-                    return deferred.promise;
-                }
-
-                if (parameters['instance'] !== undefined) {
-                    form['instance'] = parameters['instance'];
-                }
-
-                if (parameters['ip'] !== undefined) {
-                    form['ip'] = parameters['ip'];
-                }
-
-                if (parameters['port_id'] !== undefined) {
-                    form['port_id'] = parameters['port_id'];
-                }
-
-                if (parameters['mac'] !== undefined) {
-                    form['mac'] = parameters['mac'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Port_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} network - 
-             * @param {string} instance - 
-             * @param {string} ip - Instance ip address
-             * @param {string} port_id - Quantum port id
-             * @param {string} mac - MAC address associated with this port
-             * 
-             */
-            xos.prototype.Port_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/ports/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['network'] !== undefined) {
-                    form['network'] = parameters['network'];
-                }
-
-                if (parameters['instance'] !== undefined) {
-                    form['instance'] = parameters['instance'];
-                }
-
-                if (parameters['ip'] !== undefined) {
-                    form['ip'] = parameters['ip'];
-                }
-
-                if (parameters['port_id'] !== undefined) {
-                    form['port_id'] = parameters['port_id'];
-                }
-
-                if (parameters['mac'] !== undefined) {
-                    form['mac'] = parameters['mac'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Port_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Port_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/ports/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Site_List_GET
-             * 
-             */
-            xos.prototype.Controller_Site_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllersites/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Site_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} site - 
-             * @param {string} controller - 
-             * @param {string} tenant_id - Keystone tenant id
-             * 
-             */
-            xos.prototype.Controller_Site_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllersites/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['site'] !== undefined) {
-                    form['site'] = parameters['site'];
-                }
-
-                if (parameters['site'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: site'));
-                    return deferred.promise;
-                }
-
-                if (parameters['controller'] !== undefined) {
-                    form['controller'] = parameters['controller'];
-                }
-
-                if (parameters['tenant_id'] !== undefined) {
-                    form['tenant_id'] = parameters['tenant_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Site_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Controller_Site_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllersites/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Site_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} site - 
-             * @param {string} controller - 
-             * @param {string} tenant_id - Keystone tenant id
-             * 
-             */
-            xos.prototype.Controller_Site_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllersites/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['site'] !== undefined) {
-                    form['site'] = parameters['site'];
-                }
-
-                if (parameters['site'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: site'));
-                    return deferred.promise;
-                }
-
-                if (parameters['controller'] !== undefined) {
-                    form['controller'] = parameters['controller'];
-                }
-
-                if (parameters['tenant_id'] !== undefined) {
-                    form['tenant_id'] = parameters['tenant_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Site_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} site - 
-             * @param {string} controller - 
-             * @param {string} tenant_id - Keystone tenant id
-             * 
-             */
-            xos.prototype.Controller_Site_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllersites/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['site'] !== undefined) {
-                    form['site'] = parameters['site'];
-                }
-
-                if (parameters['controller'] !== undefined) {
-                    form['controller'] = parameters['controller'];
-                }
-
-                if (parameters['tenant_id'] !== undefined) {
-                    form['tenant_id'] = parameters['tenant_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Site_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Controller_Site_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllersites/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Project_List_GET
-             * 
-             */
-            xos.prototype.Project_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/projects/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Project_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - Name of Project
-             * 
-             */
-            xos.prototype.Project_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/projects/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Project_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Project_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/projects/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Project_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - Name of Project
-             * 
-             */
-            xos.prototype.Project_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/projects/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Project_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - Name of Project
-             * 
-             */
-            xos.prototype.Project_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/projects/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Project_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Project_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/projects/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Slice_List_GET
-             * 
-             */
-            xos.prototype.Slice_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/slices/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Slice_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - The Name of the Slice
-             * @param {boolean} enabled - Status for this Slice
-             * @param {boolean} omf_friendly - 
-             * @param {string} description - High level description of the slice and expected activities
-             * @param {string} slice_url - 
-             * @param {string} site - The Site this Slice belongs to
-             * @param {integer} max_instances - 
-             * @param {string} service - 
-             * @param {string} network - 
-             * @param {string} serviceClass - 
-             * @param {string} creator - 
-             * @param {string} default_flavor - 
-             * @param {string} default_image - 
-             * @param {string} mount_data_sets - 
-             * 
-             */
-            xos.prototype.Slice_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/slices/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters['omf_friendly'] !== undefined) {
-                    form['omf_friendly'] = parameters['omf_friendly'];
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['slice_url'] !== undefined) {
-                    form['slice_url'] = parameters['slice_url'];
-                }
-
-                if (parameters['site'] !== undefined) {
-                    form['site'] = parameters['site'];
-                }
-
-                if (parameters['site'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: site'));
-                    return deferred.promise;
-                }
-
-                if (parameters['max_instances'] !== undefined) {
-                    form['max_instances'] = parameters['max_instances'];
-                }
-
-                if (parameters['max_instances'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: max_instances'));
-                    return deferred.promise;
-                }
-
-                if (parameters['service'] !== undefined) {
-                    form['service'] = parameters['service'];
-                }
-
-                if (parameters['network'] !== undefined) {
-                    form['network'] = parameters['network'];
-                }
-
-                if (parameters['serviceClass'] !== undefined) {
-                    form['serviceClass'] = parameters['serviceClass'];
-                }
-
-                if (parameters['creator'] !== undefined) {
-                    form['creator'] = parameters['creator'];
-                }
-
-                if (parameters['default_flavor'] !== undefined) {
-                    form['default_flavor'] = parameters['default_flavor'];
-                }
-
-                if (parameters['default_image'] !== undefined) {
-                    form['default_image'] = parameters['default_image'];
-                }
-
-                if (parameters['mount_data_sets'] !== undefined) {
-                    form['mount_data_sets'] = parameters['mount_data_sets'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Slice_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Slice_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/slices/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Slice_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - The Name of the Slice
-             * @param {boolean} enabled - Status for this Slice
-             * @param {boolean} omf_friendly - 
-             * @param {string} description - High level description of the slice and expected activities
-             * @param {string} slice_url - 
-             * @param {string} site - The Site this Slice belongs to
-             * @param {integer} max_instances - 
-             * @param {string} service - 
-             * @param {string} network - 
-             * @param {string} serviceClass - 
-             * @param {string} creator - 
-             * @param {string} default_flavor - 
-             * @param {string} default_image - 
-             * @param {string} mount_data_sets - 
-             * 
-             */
-            xos.prototype.Slice_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/slices/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters['omf_friendly'] !== undefined) {
-                    form['omf_friendly'] = parameters['omf_friendly'];
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['slice_url'] !== undefined) {
-                    form['slice_url'] = parameters['slice_url'];
-                }
-
-                if (parameters['site'] !== undefined) {
-                    form['site'] = parameters['site'];
-                }
-
-                if (parameters['site'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: site'));
-                    return deferred.promise;
-                }
-
-                if (parameters['max_instances'] !== undefined) {
-                    form['max_instances'] = parameters['max_instances'];
-                }
-
-                if (parameters['max_instances'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: max_instances'));
-                    return deferred.promise;
-                }
-
-                if (parameters['service'] !== undefined) {
-                    form['service'] = parameters['service'];
-                }
-
-                if (parameters['network'] !== undefined) {
-                    form['network'] = parameters['network'];
-                }
-
-                if (parameters['serviceClass'] !== undefined) {
-                    form['serviceClass'] = parameters['serviceClass'];
-                }
-
-                if (parameters['creator'] !== undefined) {
-                    form['creator'] = parameters['creator'];
-                }
-
-                if (parameters['default_flavor'] !== undefined) {
-                    form['default_flavor'] = parameters['default_flavor'];
-                }
-
-                if (parameters['default_image'] !== undefined) {
-                    form['default_image'] = parameters['default_image'];
-                }
-
-                if (parameters['mount_data_sets'] !== undefined) {
-                    form['mount_data_sets'] = parameters['mount_data_sets'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Slice_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - The Name of the Slice
-             * @param {boolean} enabled - Status for this Slice
-             * @param {boolean} omf_friendly - 
-             * @param {string} description - High level description of the slice and expected activities
-             * @param {string} slice_url - 
-             * @param {string} site - The Site this Slice belongs to
-             * @param {integer} max_instances - 
-             * @param {string} service - 
-             * @param {string} network - 
-             * @param {string} serviceClass - 
-             * @param {string} creator - 
-             * @param {string} default_flavor - 
-             * @param {string} default_image - 
-             * @param {string} mount_data_sets - 
-             * 
-             */
-            xos.prototype.Slice_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/slices/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters['omf_friendly'] !== undefined) {
-                    form['omf_friendly'] = parameters['omf_friendly'];
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['slice_url'] !== undefined) {
-                    form['slice_url'] = parameters['slice_url'];
-                }
-
-                if (parameters['site'] !== undefined) {
-                    form['site'] = parameters['site'];
-                }
-
-                if (parameters['max_instances'] !== undefined) {
-                    form['max_instances'] = parameters['max_instances'];
-                }
-
-                if (parameters['service'] !== undefined) {
-                    form['service'] = parameters['service'];
-                }
-
-                if (parameters['network'] !== undefined) {
-                    form['network'] = parameters['network'];
-                }
-
-                if (parameters['serviceClass'] !== undefined) {
-                    form['serviceClass'] = parameters['serviceClass'];
-                }
-
-                if (parameters['creator'] !== undefined) {
-                    form['creator'] = parameters['creator'];
-                }
-
-                if (parameters['default_flavor'] !== undefined) {
-                    form['default_flavor'] = parameters['default_flavor'];
-                }
-
-                if (parameters['default_image'] !== undefined) {
-                    form['default_image'] = parameters['default_image'];
-                }
-
-                if (parameters['mount_data_sets'] !== undefined) {
-                    form['mount_data_sets'] = parameters['mount_data_sets'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Slice_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Slice_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/slices/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Network_List_GET
-             * 
-             */
-            xos.prototype.Network_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/networks/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Network_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - 
-             * @param {string} template - 
-             * @param {string} subnet - 
-             * @param {string} ports - 
-             * @param {string} labels - 
-             * @param {string} owner - Slice that owns control of this Network
-             * @param {integer} guaranteed_bandwidth - 
-             * @param {boolean} permit_all_slices - 
-             * @param {string} topology_parameters - 
-             * @param {string} controller_url - 
-             * @param {string} controller_parameters - 
-             * @param {string} network_id - Quantum network
-             * @param {string} router_id - Quantum router id
-             * @param {string} subnet_id - Quantum subnet id
-             * @param {boolean} autoconnect - This network can be autoconnected to the slice that owns it
-             * 
-             */
-            xos.prototype.Network_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/networks/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['template'] !== undefined) {
-                    form['template'] = parameters['template'];
-                }
-
-                if (parameters['template'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: template'));
-                    return deferred.promise;
-                }
-
-                if (parameters['subnet'] !== undefined) {
-                    form['subnet'] = parameters['subnet'];
-                }
-
-                if (parameters['ports'] !== undefined) {
-                    form['ports'] = parameters['ports'];
-                }
-
-                if (parameters['labels'] !== undefined) {
-                    form['labels'] = parameters['labels'];
-                }
-
-                if (parameters['owner'] !== undefined) {
-                    form['owner'] = parameters['owner'];
-                }
-
-                if (parameters['owner'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: owner'));
-                    return deferred.promise;
-                }
-
-                if (parameters['guaranteed_bandwidth'] !== undefined) {
-                    form['guaranteed_bandwidth'] = parameters['guaranteed_bandwidth'];
-                }
-
-                if (parameters['guaranteed_bandwidth'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: guaranteed_bandwidth'));
-                    return deferred.promise;
-                }
-
-                if (parameters['permit_all_slices'] !== undefined) {
-                    form['permit_all_slices'] = parameters['permit_all_slices'];
-                }
-
-                if (parameters['topology_parameters'] !== undefined) {
-                    form['topology_parameters'] = parameters['topology_parameters'];
-                }
-
-                if (parameters['controller_url'] !== undefined) {
-                    form['controller_url'] = parameters['controller_url'];
-                }
-
-                if (parameters['controller_parameters'] !== undefined) {
-                    form['controller_parameters'] = parameters['controller_parameters'];
-                }
-
-                if (parameters['network_id'] !== undefined) {
-                    form['network_id'] = parameters['network_id'];
-                }
-
-                if (parameters['router_id'] !== undefined) {
-                    form['router_id'] = parameters['router_id'];
-                }
-
-                if (parameters['subnet_id'] !== undefined) {
-                    form['subnet_id'] = parameters['subnet_id'];
-                }
-
-                if (parameters['autoconnect'] !== undefined) {
-                    form['autoconnect'] = parameters['autoconnect'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Network_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Network_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/networks/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Network_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - 
-             * @param {string} template - 
-             * @param {string} subnet - 
-             * @param {string} ports - 
-             * @param {string} labels - 
-             * @param {string} owner - Slice that owns control of this Network
-             * @param {integer} guaranteed_bandwidth - 
-             * @param {boolean} permit_all_slices - 
-             * @param {string} topology_parameters - 
-             * @param {string} controller_url - 
-             * @param {string} controller_parameters - 
-             * @param {string} network_id - Quantum network
-             * @param {string} router_id - Quantum router id
-             * @param {string} subnet_id - Quantum subnet id
-             * @param {boolean} autoconnect - This network can be autoconnected to the slice that owns it
-             * 
-             */
-            xos.prototype.Network_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/networks/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['template'] !== undefined) {
-                    form['template'] = parameters['template'];
-                }
-
-                if (parameters['template'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: template'));
-                    return deferred.promise;
-                }
-
-                if (parameters['subnet'] !== undefined) {
-                    form['subnet'] = parameters['subnet'];
-                }
-
-                if (parameters['ports'] !== undefined) {
-                    form['ports'] = parameters['ports'];
-                }
-
-                if (parameters['labels'] !== undefined) {
-                    form['labels'] = parameters['labels'];
-                }
-
-                if (parameters['owner'] !== undefined) {
-                    form['owner'] = parameters['owner'];
-                }
-
-                if (parameters['owner'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: owner'));
-                    return deferred.promise;
-                }
-
-                if (parameters['guaranteed_bandwidth'] !== undefined) {
-                    form['guaranteed_bandwidth'] = parameters['guaranteed_bandwidth'];
-                }
-
-                if (parameters['guaranteed_bandwidth'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: guaranteed_bandwidth'));
-                    return deferred.promise;
-                }
-
-                if (parameters['permit_all_slices'] !== undefined) {
-                    form['permit_all_slices'] = parameters['permit_all_slices'];
-                }
-
-                if (parameters['topology_parameters'] !== undefined) {
-                    form['topology_parameters'] = parameters['topology_parameters'];
-                }
-
-                if (parameters['controller_url'] !== undefined) {
-                    form['controller_url'] = parameters['controller_url'];
-                }
-
-                if (parameters['controller_parameters'] !== undefined) {
-                    form['controller_parameters'] = parameters['controller_parameters'];
-                }
-
-                if (parameters['network_id'] !== undefined) {
-                    form['network_id'] = parameters['network_id'];
-                }
-
-                if (parameters['router_id'] !== undefined) {
-                    form['router_id'] = parameters['router_id'];
-                }
-
-                if (parameters['subnet_id'] !== undefined) {
-                    form['subnet_id'] = parameters['subnet_id'];
-                }
-
-                if (parameters['autoconnect'] !== undefined) {
-                    form['autoconnect'] = parameters['autoconnect'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Network_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - 
-             * @param {string} template - 
-             * @param {string} subnet - 
-             * @param {string} ports - 
-             * @param {string} labels - 
-             * @param {string} owner - Slice that owns control of this Network
-             * @param {integer} guaranteed_bandwidth - 
-             * @param {boolean} permit_all_slices - 
-             * @param {string} topology_parameters - 
-             * @param {string} controller_url - 
-             * @param {string} controller_parameters - 
-             * @param {string} network_id - Quantum network
-             * @param {string} router_id - Quantum router id
-             * @param {string} subnet_id - Quantum subnet id
-             * @param {boolean} autoconnect - This network can be autoconnected to the slice that owns it
-             * 
-             */
-            xos.prototype.Network_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/networks/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['template'] !== undefined) {
-                    form['template'] = parameters['template'];
-                }
-
-                if (parameters['subnet'] !== undefined) {
-                    form['subnet'] = parameters['subnet'];
-                }
-
-                if (parameters['ports'] !== undefined) {
-                    form['ports'] = parameters['ports'];
-                }
-
-                if (parameters['labels'] !== undefined) {
-                    form['labels'] = parameters['labels'];
-                }
-
-                if (parameters['owner'] !== undefined) {
-                    form['owner'] = parameters['owner'];
-                }
-
-                if (parameters['guaranteed_bandwidth'] !== undefined) {
-                    form['guaranteed_bandwidth'] = parameters['guaranteed_bandwidth'];
-                }
-
-                if (parameters['permit_all_slices'] !== undefined) {
-                    form['permit_all_slices'] = parameters['permit_all_slices'];
-                }
-
-                if (parameters['topology_parameters'] !== undefined) {
-                    form['topology_parameters'] = parameters['topology_parameters'];
-                }
-
-                if (parameters['controller_url'] !== undefined) {
-                    form['controller_url'] = parameters['controller_url'];
-                }
-
-                if (parameters['controller_parameters'] !== undefined) {
-                    form['controller_parameters'] = parameters['controller_parameters'];
-                }
-
-                if (parameters['network_id'] !== undefined) {
-                    form['network_id'] = parameters['network_id'];
-                }
-
-                if (parameters['router_id'] !== undefined) {
-                    form['router_id'] = parameters['router_id'];
-                }
-
-                if (parameters['subnet_id'] !== undefined) {
-                    form['subnet_id'] = parameters['subnet_id'];
-                }
-
-                if (parameters['autoconnect'] !== undefined) {
-                    form['autoconnect'] = parameters['autoconnect'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Network_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Network_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/networks/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Service_List_GET
-             * 
-             */
-            xos.prototype.Service_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/services/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Service_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} description - Description of Service
-             * @param {boolean} enabled - 
-             * @param {string} kind - Kind of service
-             * @param {string} name - Service Name
-             * @param {string} versionNumber - Version of Service Definition
-             * @param {boolean} published - 
-             * @param {string} view_url - 
-             * @param {string} icon_url - 
-             * @param {string} public_key - Public key string
-             * @param {string} service_specific_id - 
-             * @param {string} service_specific_attribute - 
-             * 
-             */
-            xos.prototype.Service_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/services/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters['kind'] !== undefined) {
-                    form['kind'] = parameters['kind'];
-                }
-
-                if (parameters['kind'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: kind'));
-                    return deferred.promise;
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['versionNumber'] !== undefined) {
-                    form['versionNumber'] = parameters['versionNumber'];
-                }
-
-                if (parameters['versionNumber'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: versionNumber'));
-                    return deferred.promise;
-                }
-
-                if (parameters['published'] !== undefined) {
-                    form['published'] = parameters['published'];
-                }
-
-                if (parameters['view_url'] !== undefined) {
-                    form['view_url'] = parameters['view_url'];
-                }
-
-                if (parameters['icon_url'] !== undefined) {
-                    form['icon_url'] = parameters['icon_url'];
-                }
-
-                if (parameters['public_key'] !== undefined) {
-                    form['public_key'] = parameters['public_key'];
-                }
-
-                if (parameters['service_specific_id'] !== undefined) {
-                    form['service_specific_id'] = parameters['service_specific_id'];
-                }
-
-                if (parameters['service_specific_attribute'] !== undefined) {
-                    form['service_specific_attribute'] = parameters['service_specific_attribute'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Service_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Service_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/services/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Service_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} description - Description of Service
-             * @param {boolean} enabled - 
-             * @param {string} kind - Kind of service
-             * @param {string} name - Service Name
-             * @param {string} versionNumber - Version of Service Definition
-             * @param {boolean} published - 
-             * @param {string} view_url - 
-             * @param {string} icon_url - 
-             * @param {string} public_key - Public key string
-             * @param {string} service_specific_id - 
-             * @param {string} service_specific_attribute - 
-             * 
-             */
-            xos.prototype.Service_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/services/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters['kind'] !== undefined) {
-                    form['kind'] = parameters['kind'];
-                }
-
-                if (parameters['kind'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: kind'));
-                    return deferred.promise;
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['versionNumber'] !== undefined) {
-                    form['versionNumber'] = parameters['versionNumber'];
-                }
-
-                if (parameters['versionNumber'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: versionNumber'));
-                    return deferred.promise;
-                }
-
-                if (parameters['published'] !== undefined) {
-                    form['published'] = parameters['published'];
-                }
-
-                if (parameters['view_url'] !== undefined) {
-                    form['view_url'] = parameters['view_url'];
-                }
-
-                if (parameters['icon_url'] !== undefined) {
-                    form['icon_url'] = parameters['icon_url'];
-                }
-
-                if (parameters['public_key'] !== undefined) {
-                    form['public_key'] = parameters['public_key'];
-                }
-
-                if (parameters['service_specific_id'] !== undefined) {
-                    form['service_specific_id'] = parameters['service_specific_id'];
-                }
-
-                if (parameters['service_specific_attribute'] !== undefined) {
-                    form['service_specific_attribute'] = parameters['service_specific_attribute'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Service_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} description - Description of Service
-             * @param {boolean} enabled - 
-             * @param {string} kind - Kind of service
-             * @param {string} name - Service Name
-             * @param {string} versionNumber - Version of Service Definition
-             * @param {boolean} published - 
-             * @param {string} view_url - 
-             * @param {string} icon_url - 
-             * @param {string} public_key - Public key string
-             * @param {string} service_specific_id - 
-             * @param {string} service_specific_attribute - 
-             * 
-             */
-            xos.prototype.Service_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/services/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters['kind'] !== undefined) {
-                    form['kind'] = parameters['kind'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['versionNumber'] !== undefined) {
-                    form['versionNumber'] = parameters['versionNumber'];
-                }
-
-                if (parameters['published'] !== undefined) {
-                    form['published'] = parameters['published'];
-                }
-
-                if (parameters['view_url'] !== undefined) {
-                    form['view_url'] = parameters['view_url'];
-                }
-
-                if (parameters['icon_url'] !== undefined) {
-                    form['icon_url'] = parameters['icon_url'];
-                }
-
-                if (parameters['public_key'] !== undefined) {
-                    form['public_key'] = parameters['public_key'];
-                }
-
-                if (parameters['service_specific_id'] !== undefined) {
-                    form['service_specific_id'] = parameters['service_specific_id'];
-                }
-
-                if (parameters['service_specific_attribute'] !== undefined) {
-                    form['service_specific_attribute'] = parameters['service_specific_attribute'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Service_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Service_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/services/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Service_Class_List_GET
-             * 
-             */
-            xos.prototype.Service_Class_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/serviceclasses/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Service_Class_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - 
-             * @param {string} description - 
-             * @param {integer} commitment - 
-             * @param {integer} membershipFee - 
-             * @param {integer} membershipFeeMonths - 
-             * @param {boolean} upgradeRequiresApproval - 
-             * 
-             */
-            xos.prototype.Service_Class_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/serviceclasses/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['description'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: description'));
-                    return deferred.promise;
-                }
-
-                if (parameters['commitment'] !== undefined) {
-                    form['commitment'] = parameters['commitment'];
-                }
-
-                if (parameters['commitment'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: commitment'));
-                    return deferred.promise;
-                }
-
-                if (parameters['membershipFee'] !== undefined) {
-                    form['membershipFee'] = parameters['membershipFee'];
-                }
-
-                if (parameters['membershipFee'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: membershipFee'));
-                    return deferred.promise;
-                }
-
-                if (parameters['membershipFeeMonths'] !== undefined) {
-                    form['membershipFeeMonths'] = parameters['membershipFeeMonths'];
-                }
-
-                if (parameters['membershipFeeMonths'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: membershipFeeMonths'));
-                    return deferred.promise;
-                }
-
-                if (parameters['upgradeRequiresApproval'] !== undefined) {
-                    form['upgradeRequiresApproval'] = parameters['upgradeRequiresApproval'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Service_Class_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Service_Class_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/serviceclasses/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Service_Class_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - 
-             * @param {string} description - 
-             * @param {integer} commitment - 
-             * @param {integer} membershipFee - 
-             * @param {integer} membershipFeeMonths - 
-             * @param {boolean} upgradeRequiresApproval - 
-             * 
-             */
-            xos.prototype.Service_Class_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/serviceclasses/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['description'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: description'));
-                    return deferred.promise;
-                }
-
-                if (parameters['commitment'] !== undefined) {
-                    form['commitment'] = parameters['commitment'];
-                }
-
-                if (parameters['commitment'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: commitment'));
-                    return deferred.promise;
-                }
-
-                if (parameters['membershipFee'] !== undefined) {
-                    form['membershipFee'] = parameters['membershipFee'];
-                }
-
-                if (parameters['membershipFee'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: membershipFee'));
-                    return deferred.promise;
-                }
-
-                if (parameters['membershipFeeMonths'] !== undefined) {
-                    form['membershipFeeMonths'] = parameters['membershipFeeMonths'];
-                }
-
-                if (parameters['membershipFeeMonths'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: membershipFeeMonths'));
-                    return deferred.promise;
-                }
-
-                if (parameters['upgradeRequiresApproval'] !== undefined) {
-                    form['upgradeRequiresApproval'] = parameters['upgradeRequiresApproval'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Service_Class_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - 
-             * @param {string} description - 
-             * @param {integer} commitment - 
-             * @param {integer} membershipFee - 
-             * @param {integer} membershipFeeMonths - 
-             * @param {boolean} upgradeRequiresApproval - 
-             * 
-             */
-            xos.prototype.Service_Class_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/serviceclasses/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['commitment'] !== undefined) {
-                    form['commitment'] = parameters['commitment'];
-                }
-
-                if (parameters['membershipFee'] !== undefined) {
-                    form['membershipFee'] = parameters['membershipFee'];
-                }
-
-                if (parameters['membershipFeeMonths'] !== undefined) {
-                    form['membershipFeeMonths'] = parameters['membershipFeeMonths'];
-                }
-
-                if (parameters['upgradeRequiresApproval'] !== undefined) {
-                    form['upgradeRequiresApproval'] = parameters['upgradeRequiresApproval'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Service_Class_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Service_Class_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/serviceclasses/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Payment_List_GET
-             * 
-             */
-            xos.prototype.Payment_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/payments/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Payment_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} account - 
-             * @param {number} amount - 
-             * @param {string} date - 
-             * 
-             */
-            xos.prototype.Payment_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/payments/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['account'] !== undefined) {
-                    form['account'] = parameters['account'];
-                }
-
-                if (parameters['account'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: account'));
-                    return deferred.promise;
-                }
-
-                if (parameters['amount'] !== undefined) {
-                    form['amount'] = parameters['amount'];
-                }
-
-                if (parameters['amount'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: amount'));
-                    return deferred.promise;
-                }
-
-                if (parameters['date'] !== undefined) {
-                    form['date'] = parameters['date'];
-                }
-
-                if (parameters['date'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: date'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Payment_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Payment_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/payments/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Payment_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} account - 
-             * @param {number} amount - 
-             * @param {string} date - 
-             * 
-             */
-            xos.prototype.Payment_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/payments/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['account'] !== undefined) {
-                    form['account'] = parameters['account'];
-                }
-
-                if (parameters['account'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: account'));
-                    return deferred.promise;
-                }
-
-                if (parameters['amount'] !== undefined) {
-                    form['amount'] = parameters['amount'];
-                }
-
-                if (parameters['amount'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: amount'));
-                    return deferred.promise;
-                }
-
-                if (parameters['date'] !== undefined) {
-                    form['date'] = parameters['date'];
-                }
-
-                if (parameters['date'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: date'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Payment_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} account - 
-             * @param {number} amount - 
-             * @param {string} date - 
-             * 
-             */
-            xos.prototype.Payment_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/payments/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['account'] !== undefined) {
-                    form['account'] = parameters['account'];
-                }
-
-                if (parameters['amount'] !== undefined) {
-                    form['amount'] = parameters['amount'];
-                }
-
-                if (parameters['date'] !== undefined) {
-                    form['date'] = parameters['date'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Payment_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Payment_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/payments/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Subscriber_List_GET
-             * 
-             */
-            xos.prototype.Subscriber_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/subscribers/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Subscriber_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} kind - 
-             * @param {string} name - name
-             * @param {string} service_specific_attribute - 
-             * @param {string} service_specific_id - 
-             * 
-             */
-            xos.prototype.Subscriber_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/subscribers/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['kind'] !== undefined) {
-                    form['kind'] = parameters['kind'];
-                }
-
-                if (parameters['kind'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: kind'));
-                    return deferred.promise;
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['service_specific_attribute'] !== undefined) {
-                    form['service_specific_attribute'] = parameters['service_specific_attribute'];
-                }
-
-                if (parameters['service_specific_id'] !== undefined) {
-                    form['service_specific_id'] = parameters['service_specific_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Subscriber_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Subscriber_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/subscribers/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Subscriber_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} kind - 
-             * @param {string} name - name
-             * @param {string} service_specific_attribute - 
-             * @param {string} service_specific_id - 
-             * 
-             */
-            xos.prototype.Subscriber_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/subscribers/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['kind'] !== undefined) {
-                    form['kind'] = parameters['kind'];
-                }
-
-                if (parameters['kind'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: kind'));
-                    return deferred.promise;
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['service_specific_attribute'] !== undefined) {
-                    form['service_specific_attribute'] = parameters['service_specific_attribute'];
-                }
-
-                if (parameters['service_specific_id'] !== undefined) {
-                    form['service_specific_id'] = parameters['service_specific_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Subscriber_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} kind - 
-             * @param {string} name - name
-             * @param {string} service_specific_attribute - 
-             * @param {string} service_specific_id - 
-             * 
-             */
-            xos.prototype.Subscriber_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/subscribers/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['kind'] !== undefined) {
-                    form['kind'] = parameters['kind'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['service_specific_attribute'] !== undefined) {
-                    form['service_specific_attribute'] = parameters['service_specific_attribute'];
-                }
-
-                if (parameters['service_specific_id'] !== undefined) {
-                    form['service_specific_id'] = parameters['service_specific_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Subscriber_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Subscriber_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/subscribers/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Instance_List_GET
-             * 
-             */
-            xos.prototype.Instance_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/instances/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Instance_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} instance_id - Nova instance id
-             * @param {string} instance_uuid - Nova instance uuid
-             * @param {string} name - Instance name
-             * @param {string} instance_name - OpenStack generated name
-             * @param {string} ip - Instance ip address
-             * @param {string} image - 
-             * @param {string} creator - 
-             * @param {string} slice - 
-             * @param {string} deployment - 
-             * @param {string} node - 
-             * @param {integer} numberCores - Number of cores for instance
-             * @param {string} flavor - Flavor of this instance
-             * @param {string} userData - user_data passed to instance during creation
-             * 
-             */
-            xos.prototype.Instance_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/instances/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['instance_id'] !== undefined) {
-                    form['instance_id'] = parameters['instance_id'];
-                }
-
-                if (parameters['instance_uuid'] !== undefined) {
-                    form['instance_uuid'] = parameters['instance_uuid'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['instance_name'] !== undefined) {
-                    form['instance_name'] = parameters['instance_name'];
-                }
-
-                if (parameters['ip'] !== undefined) {
-                    form['ip'] = parameters['ip'];
-                }
-
-                if (parameters['image'] !== undefined) {
-                    form['image'] = parameters['image'];
-                }
-
-                if (parameters['image'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: image'));
-                    return deferred.promise;
-                }
-
-                if (parameters['creator'] !== undefined) {
-                    form['creator'] = parameters['creator'];
-                }
-
-                if (parameters['slice'] !== undefined) {
-                    form['slice'] = parameters['slice'];
-                }
-
-                if (parameters['slice'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: slice'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deployment'] !== undefined) {
-                    form['deployment'] = parameters['deployment'];
-                }
-
-                if (parameters['deployment'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: deployment'));
-                    return deferred.promise;
-                }
-
-                if (parameters['node'] !== undefined) {
-                    form['node'] = parameters['node'];
-                }
-
-                if (parameters['node'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: node'));
-                    return deferred.promise;
-                }
-
-                if (parameters['numberCores'] !== undefined) {
-                    form['numberCores'] = parameters['numberCores'];
-                }
-
-                if (parameters['numberCores'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: numberCores'));
-                    return deferred.promise;
-                }
-
-                if (parameters['flavor'] !== undefined) {
-                    form['flavor'] = parameters['flavor'];
-                }
-
-                if (parameters['flavor'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: flavor'));
-                    return deferred.promise;
-                }
-
-                if (parameters['userData'] !== undefined) {
-                    form['userData'] = parameters['userData'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Instance_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Instance_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/instances/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Instance_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} instance_id - Nova instance id
-             * @param {string} instance_uuid - Nova instance uuid
-             * @param {string} name - Instance name
-             * @param {string} instance_name - OpenStack generated name
-             * @param {string} ip - Instance ip address
-             * @param {string} image - 
-             * @param {string} creator - 
-             * @param {string} slice - 
-             * @param {string} deployment - 
-             * @param {string} node - 
-             * @param {integer} numberCores - Number of cores for instance
-             * @param {string} flavor - Flavor of this instance
-             * @param {string} userData - user_data passed to instance during creation
-             * 
-             */
-            xos.prototype.Instance_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/instances/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['instance_id'] !== undefined) {
-                    form['instance_id'] = parameters['instance_id'];
-                }
-
-                if (parameters['instance_uuid'] !== undefined) {
-                    form['instance_uuid'] = parameters['instance_uuid'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['instance_name'] !== undefined) {
-                    form['instance_name'] = parameters['instance_name'];
-                }
-
-                if (parameters['ip'] !== undefined) {
-                    form['ip'] = parameters['ip'];
-                }
-
-                if (parameters['image'] !== undefined) {
-                    form['image'] = parameters['image'];
-                }
-
-                if (parameters['image'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: image'));
-                    return deferred.promise;
-                }
-
-                if (parameters['creator'] !== undefined) {
-                    form['creator'] = parameters['creator'];
-                }
-
-                if (parameters['slice'] !== undefined) {
-                    form['slice'] = parameters['slice'];
-                }
-
-                if (parameters['slice'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: slice'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deployment'] !== undefined) {
-                    form['deployment'] = parameters['deployment'];
-                }
-
-                if (parameters['deployment'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: deployment'));
-                    return deferred.promise;
-                }
-
-                if (parameters['node'] !== undefined) {
-                    form['node'] = parameters['node'];
-                }
-
-                if (parameters['node'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: node'));
-                    return deferred.promise;
-                }
-
-                if (parameters['numberCores'] !== undefined) {
-                    form['numberCores'] = parameters['numberCores'];
-                }
-
-                if (parameters['numberCores'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: numberCores'));
-                    return deferred.promise;
-                }
-
-                if (parameters['flavor'] !== undefined) {
-                    form['flavor'] = parameters['flavor'];
-                }
-
-                if (parameters['flavor'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: flavor'));
-                    return deferred.promise;
-                }
-
-                if (parameters['userData'] !== undefined) {
-                    form['userData'] = parameters['userData'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Instance_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} instance_id - Nova instance id
-             * @param {string} instance_uuid - Nova instance uuid
-             * @param {string} name - Instance name
-             * @param {string} instance_name - OpenStack generated name
-             * @param {string} ip - Instance ip address
-             * @param {string} image - 
-             * @param {string} creator - 
-             * @param {string} slice - 
-             * @param {string} deployment - 
-             * @param {string} node - 
-             * @param {integer} numberCores - Number of cores for instance
-             * @param {string} flavor - Flavor of this instance
-             * @param {string} userData - user_data passed to instance during creation
-             * 
-             */
-            xos.prototype.Instance_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/instances/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['instance_id'] !== undefined) {
-                    form['instance_id'] = parameters['instance_id'];
-                }
-
-                if (parameters['instance_uuid'] !== undefined) {
-                    form['instance_uuid'] = parameters['instance_uuid'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['instance_name'] !== undefined) {
-                    form['instance_name'] = parameters['instance_name'];
-                }
-
-                if (parameters['ip'] !== undefined) {
-                    form['ip'] = parameters['ip'];
-                }
-
-                if (parameters['image'] !== undefined) {
-                    form['image'] = parameters['image'];
-                }
-
-                if (parameters['creator'] !== undefined) {
-                    form['creator'] = parameters['creator'];
-                }
-
-                if (parameters['slice'] !== undefined) {
-                    form['slice'] = parameters['slice'];
-                }
-
-                if (parameters['deployment'] !== undefined) {
-                    form['deployment'] = parameters['deployment'];
-                }
-
-                if (parameters['node'] !== undefined) {
-                    form['node'] = parameters['node'];
-                }
-
-                if (parameters['numberCores'] !== undefined) {
-                    form['numberCores'] = parameters['numberCores'];
-                }
-
-                if (parameters['flavor'] !== undefined) {
-                    form['flavor'] = parameters['flavor'];
-                }
-
-                if (parameters['userData'] !== undefined) {
-                    form['userData'] = parameters['userData'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Instance_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Instance_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/instances/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Charge_List_GET
-             * 
-             */
-            xos.prototype.Charge_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/charges/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Charge_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} account - 
-             * @param {string} slice - 
-             * @param {choice} kind - 
-             * @param {choice} state - 
-             * @param {string} date - 
-             * @param {string} object - 
-             * @param {number} amount - 
-             * @param {number} coreHours - 
-             * @param {string} invoice - 
-             * 
-             */
-            xos.prototype.Charge_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/charges/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['account'] !== undefined) {
-                    form['account'] = parameters['account'];
-                }
-
-                if (parameters['account'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: account'));
-                    return deferred.promise;
-                }
-
-                if (parameters['slice'] !== undefined) {
-                    form['slice'] = parameters['slice'];
-                }
-
-                if (parameters['kind'] !== undefined) {
-                    form['kind'] = parameters['kind'];
-                }
-
-                if (parameters['kind'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: kind'));
-                    return deferred.promise;
-                }
-
-                if (parameters['state'] !== undefined) {
-                    form['state'] = parameters['state'];
-                }
-
-                if (parameters['state'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: state'));
-                    return deferred.promise;
-                }
-
-                if (parameters['date'] !== undefined) {
-                    form['date'] = parameters['date'];
-                }
-
-                if (parameters['date'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: date'));
-                    return deferred.promise;
-                }
-
-                if (parameters['object'] !== undefined) {
-                    form['object'] = parameters['object'];
-                }
-
-                if (parameters['object'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: object'));
-                    return deferred.promise;
-                }
-
-                if (parameters['amount'] !== undefined) {
-                    form['amount'] = parameters['amount'];
-                }
-
-                if (parameters['amount'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: amount'));
-                    return deferred.promise;
-                }
-
-                if (parameters['coreHours'] !== undefined) {
-                    form['coreHours'] = parameters['coreHours'];
-                }
-
-                if (parameters['coreHours'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: coreHours'));
-                    return deferred.promise;
-                }
-
-                if (parameters['invoice'] !== undefined) {
-                    form['invoice'] = parameters['invoice'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Charge_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Charge_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/charges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Charge_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} account - 
-             * @param {string} slice - 
-             * @param {choice} kind - 
-             * @param {choice} state - 
-             * @param {string} date - 
-             * @param {string} object - 
-             * @param {number} amount - 
-             * @param {number} coreHours - 
-             * @param {string} invoice - 
-             * 
-             */
-            xos.prototype.Charge_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/charges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['account'] !== undefined) {
-                    form['account'] = parameters['account'];
-                }
-
-                if (parameters['account'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: account'));
-                    return deferred.promise;
-                }
-
-                if (parameters['slice'] !== undefined) {
-                    form['slice'] = parameters['slice'];
-                }
-
-                if (parameters['kind'] !== undefined) {
-                    form['kind'] = parameters['kind'];
-                }
-
-                if (parameters['kind'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: kind'));
-                    return deferred.promise;
-                }
-
-                if (parameters['state'] !== undefined) {
-                    form['state'] = parameters['state'];
-                }
-
-                if (parameters['state'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: state'));
-                    return deferred.promise;
-                }
-
-                if (parameters['date'] !== undefined) {
-                    form['date'] = parameters['date'];
-                }
-
-                if (parameters['date'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: date'));
-                    return deferred.promise;
-                }
-
-                if (parameters['object'] !== undefined) {
-                    form['object'] = parameters['object'];
-                }
-
-                if (parameters['object'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: object'));
-                    return deferred.promise;
-                }
-
-                if (parameters['amount'] !== undefined) {
-                    form['amount'] = parameters['amount'];
-                }
-
-                if (parameters['amount'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: amount'));
-                    return deferred.promise;
-                }
-
-                if (parameters['coreHours'] !== undefined) {
-                    form['coreHours'] = parameters['coreHours'];
-                }
-
-                if (parameters['coreHours'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: coreHours'));
-                    return deferred.promise;
-                }
-
-                if (parameters['invoice'] !== undefined) {
-                    form['invoice'] = parameters['invoice'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Charge_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} account - 
-             * @param {string} slice - 
-             * @param {choice} kind - 
-             * @param {choice} state - 
-             * @param {string} date - 
-             * @param {string} object - 
-             * @param {number} amount - 
-             * @param {number} coreHours - 
-             * @param {string} invoice - 
-             * 
-             */
-            xos.prototype.Charge_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/charges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['account'] !== undefined) {
-                    form['account'] = parameters['account'];
-                }
-
-                if (parameters['slice'] !== undefined) {
-                    form['slice'] = parameters['slice'];
-                }
-
-                if (parameters['kind'] !== undefined) {
-                    form['kind'] = parameters['kind'];
-                }
-
-                if (parameters['state'] !== undefined) {
-                    form['state'] = parameters['state'];
-                }
-
-                if (parameters['date'] !== undefined) {
-                    form['date'] = parameters['date'];
-                }
-
-                if (parameters['object'] !== undefined) {
-                    form['object'] = parameters['object'];
-                }
-
-                if (parameters['amount'] !== undefined) {
-                    form['amount'] = parameters['amount'];
-                }
-
-                if (parameters['coreHours'] !== undefined) {
-                    form['coreHours'] = parameters['coreHours'];
-                }
-
-                if (parameters['invoice'] !== undefined) {
-                    form['invoice'] = parameters['invoice'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Charge_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Charge_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/charges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Program_List_GET
-             * 
-             */
-            xos.prototype.Program_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/programs/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Program_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - Service Name
-             * @param {string} description - Description of Service
-
-             * @param {choice} command - Command to run
-             * @param {string} owner - 
-             * @param {string} contents - Contents of Program
-             * @param {string} output - Output of Program
-             * @param {string} messages - Debug messages
-             * @param {string} status - Status of program
-             * 
-             */
-            xos.prototype.Program_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/programs/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                form['kind'] = 'tosca';
-
-                if (parameters['kind'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: kind'));
-                    return deferred.promise;
-                }
-
-                if (parameters['command'] !== undefined) {
-                    form['command'] = parameters['command'];
-                }
-
-                if (parameters['owner'] !== undefined) {
-                    form['owner'] = parameters['owner'];
-                }
-
-                if (parameters['contents'] !== undefined) {
-                    form['contents'] = parameters['contents'];
-                }
-
-                if (parameters['output'] !== undefined) {
-                    form['output'] = parameters['output'];
-                }
-
-                if (parameters['messages'] !== undefined) {
-                    form['messages'] = parameters['messages'];
-                }
-
-                if (parameters['status'] !== undefined) {
-                    form['status'] = parameters['status'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Program_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Program_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/programs/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Program_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - Service Name
-             * @param {string} description - Description of Service
-
-             * @param {choice} command - Command to run
-             * @param {string} owner - 
-             * @param {string} contents - Contents of Program
-             * @param {string} output - Output of Program
-             * @param {string} messages - Debug messages
-             * @param {string} status - Status of program
-             * 
-             */
-            xos.prototype.Program_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/programs/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                form['kind'] = 'tosca';
-
-                if (parameters['kind'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: kind'));
-                    return deferred.promise;
-                }
-
-                if (parameters['command'] !== undefined) {
-                    form['command'] = parameters['command'];
-                }
-
-                if (parameters['owner'] !== undefined) {
-                    form['owner'] = parameters['owner'];
-                }
-
-                if (parameters['contents'] !== undefined) {
-                    form['contents'] = parameters['contents'];
-                }
-
-                if (parameters['output'] !== undefined) {
-                    form['output'] = parameters['output'];
-                }
-
-                if (parameters['messages'] !== undefined) {
-                    form['messages'] = parameters['messages'];
-                }
-
-                if (parameters['status'] !== undefined) {
-                    form['status'] = parameters['status'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Program_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - Service Name
-             * @param {string} description - Description of Service
-
-             * @param {choice} command - Command to run
-             * @param {string} owner - 
-             * @param {string} contents - Contents of Program
-             * @param {string} output - Output of Program
-             * @param {string} messages - Debug messages
-             * @param {string} status - Status of program
-             * 
-             */
-            xos.prototype.Program_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/programs/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                form['kind'] = 'tosca';
-
-                if (parameters['command'] !== undefined) {
-                    form['command'] = parameters['command'];
-                }
-
-                if (parameters['owner'] !== undefined) {
-                    form['owner'] = parameters['owner'];
-                }
-
-                if (parameters['contents'] !== undefined) {
-                    form['contents'] = parameters['contents'];
-                }
-
-                if (parameters['output'] !== undefined) {
-                    form['output'] = parameters['output'];
-                }
-
-                if (parameters['messages'] !== undefined) {
-                    form['messages'] = parameters['messages'];
-                }
-
-                if (parameters['status'] !== undefined) {
-                    form['status'] = parameters['status'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Program_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Program_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/programs/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Role_List_GET
-             * 
-             */
-            xos.prototype.Role_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/roles/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Role_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} role_type - 
-             * @param {string} role - 
-             * @param {string} description - 
-             * @param {string} content_type - 
-             * 
-             */
-            xos.prototype.Role_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/roles/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['role_type'] !== undefined) {
-                    form['role_type'] = parameters['role_type'];
-                }
-
-                if (parameters['role_type'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: role_type'));
-                    return deferred.promise;
-                }
-
-                if (parameters['role'] !== undefined) {
-                    form['role'] = parameters['role'];
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['description'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: description'));
-                    return deferred.promise;
-                }
-
-                if (parameters['content_type'] !== undefined) {
-                    form['content_type'] = parameters['content_type'];
-                }
-
-                if (parameters['content_type'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: content_type'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Role_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Role_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/roles/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Role_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} role_type - 
-             * @param {string} role - 
-             * @param {string} description - 
-             * @param {string} content_type - 
-             * 
-             */
-            xos.prototype.Role_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/roles/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['role_type'] !== undefined) {
-                    form['role_type'] = parameters['role_type'];
-                }
-
-                if (parameters['role_type'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: role_type'));
-                    return deferred.promise;
-                }
-
-                if (parameters['role'] !== undefined) {
-                    form['role'] = parameters['role'];
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['description'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: description'));
-                    return deferred.promise;
-                }
-
-                if (parameters['content_type'] !== undefined) {
-                    form['content_type'] = parameters['content_type'];
-                }
-
-                if (parameters['content_type'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: content_type'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Role_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} role_type - 
-             * @param {string} role - 
-             * @param {string} description - 
-             * @param {string} content_type - 
-             * 
-             */
-            xos.prototype.Role_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/roles/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['role_type'] !== undefined) {
-                    form['role_type'] = parameters['role_type'];
-                }
-
-                if (parameters['role'] !== undefined) {
-                    form['role'] = parameters['role'];
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['content_type'] !== undefined) {
-                    form['content_type'] = parameters['content_type'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Role_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Role_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/roles/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Usable_Object_List_GET
-             * 
-             */
-            xos.prototype.Usable_Object_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/usableobjects/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Usable_Object_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - 
-             * 
-             */
-            xos.prototype.Usable_Object_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/usableobjects/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Usable_Object_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Usable_Object_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/usableobjects/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Usable_Object_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - 
-             * 
-             */
-            xos.prototype.Usable_Object_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/usableobjects/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Usable_Object_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - 
-             * 
-             */
-            xos.prototype.Usable_Object_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/usableobjects/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Usable_Object_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Usable_Object_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/usableobjects/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Provider_List_GET
-             * 
-             */
-            xos.prototype.Provider_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/providers/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Provider_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} kind - 
-             * @param {string} name - name
-             * @param {string} service_specific_attribute - 
-             * @param {string} service_specific_id - 
-             * 
-             */
-            xos.prototype.Provider_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/providers/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['kind'] !== undefined) {
-                    form['kind'] = parameters['kind'];
-                }
-
-                if (parameters['kind'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: kind'));
-                    return deferred.promise;
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['service_specific_attribute'] !== undefined) {
-                    form['service_specific_attribute'] = parameters['service_specific_attribute'];
-                }
-
-                if (parameters['service_specific_id'] !== undefined) {
-                    form['service_specific_id'] = parameters['service_specific_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Provider_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Provider_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/providers/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Provider_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} kind - 
-             * @param {string} name - name
-             * @param {string} service_specific_attribute - 
-             * @param {string} service_specific_id - 
-             * 
-             */
-            xos.prototype.Provider_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/providers/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['kind'] !== undefined) {
-                    form['kind'] = parameters['kind'];
-                }
-
-                if (parameters['kind'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: kind'));
-                    return deferred.promise;
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['service_specific_attribute'] !== undefined) {
-                    form['service_specific_attribute'] = parameters['service_specific_attribute'];
-                }
-
-                if (parameters['service_specific_id'] !== undefined) {
-                    form['service_specific_id'] = parameters['service_specific_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Provider_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} kind - 
-             * @param {string} name - name
-             * @param {string} service_specific_attribute - 
-             * @param {string} service_specific_id - 
-             * 
-             */
-            xos.prototype.Provider_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/providers/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['kind'] !== undefined) {
-                    form['kind'] = parameters['kind'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['service_specific_attribute'] !== undefined) {
-                    form['service_specific_attribute'] = parameters['service_specific_attribute'];
-                }
-
-                if (parameters['service_specific_id'] !== undefined) {
-                    form['service_specific_id'] = parameters['service_specific_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Provider_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Provider_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/providers/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Slice_Credential_List_GET
-             * 
-             */
-            xos.prototype.Slice_Credential_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/slicecredentials/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Slice_Credential_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} slice - The User this credential is associated with
-             * @param {string} name - The credential type, e.g. ec2
-             * @param {string} key_id - The backend id of this credential
-             * @param {string} enc_value - The key value of this credential
-             * 
-             */
-            xos.prototype.Slice_Credential_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/slicecredentials/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['slice'] !== undefined) {
-                    form['slice'] = parameters['slice'];
-                }
-
-                if (parameters['slice'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: slice'));
-                    return deferred.promise;
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['key_id'] !== undefined) {
-                    form['key_id'] = parameters['key_id'];
-                }
-
-                if (parameters['key_id'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: key_id'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enc_value'] !== undefined) {
-                    form['enc_value'] = parameters['enc_value'];
-                }
-
-                if (parameters['enc_value'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: enc_value'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Slice_Credential_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Slice_Credential_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/slicecredentials/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Slice_Credential_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} slice - The User this credential is associated with
-             * @param {string} name - The credential type, e.g. ec2
-             * @param {string} key_id - The backend id of this credential
-             * @param {string} enc_value - The key value of this credential
-             * 
-             */
-            xos.prototype.Slice_Credential_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/slicecredentials/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['slice'] !== undefined) {
-                    form['slice'] = parameters['slice'];
-                }
-
-                if (parameters['slice'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: slice'));
-                    return deferred.promise;
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['key_id'] !== undefined) {
-                    form['key_id'] = parameters['key_id'];
-                }
-
-                if (parameters['key_id'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: key_id'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enc_value'] !== undefined) {
-                    form['enc_value'] = parameters['enc_value'];
-                }
-
-                if (parameters['enc_value'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: enc_value'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Slice_Credential_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} slice - The User this credential is associated with
-             * @param {string} name - The credential type, e.g. ec2
-             * @param {string} key_id - The backend id of this credential
-             * @param {string} enc_value - The key value of this credential
-             * 
-             */
-            xos.prototype.Slice_Credential_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/slicecredentials/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['slice'] !== undefined) {
-                    form['slice'] = parameters['slice'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['key_id'] !== undefined) {
-                    form['key_id'] = parameters['key_id'];
-                }
-
-                if (parameters['enc_value'] !== undefined) {
-                    form['enc_value'] = parameters['enc_value'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Slice_Credential_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Slice_Credential_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/slicecredentials/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Node_List_GET
-             * 
-             */
-            xos.prototype.Node_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/nodes/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Node_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - Name of the Node
-             * @param {string} site_deployment - 
-             * @param {string} site - 
-             * 
-             */
-            xos.prototype.Node_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/nodes/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['site_deployment'] !== undefined) {
-                    form['site_deployment'] = parameters['site_deployment'];
-                }
-
-                if (parameters['site_deployment'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: site_deployment'));
-                    return deferred.promise;
-                }
-
-                if (parameters['site'] !== undefined) {
-                    form['site'] = parameters['site'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Node_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Node_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/nodes/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Node_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - Name of the Node
-             * @param {string} site_deployment - 
-             * @param {string} site - 
-             * 
-             */
-            xos.prototype.Node_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/nodes/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['site_deployment'] !== undefined) {
-                    form['site_deployment'] = parameters['site_deployment'];
-                }
-
-                if (parameters['site_deployment'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: site_deployment'));
-                    return deferred.promise;
-                }
-
-                if (parameters['site'] !== undefined) {
-                    form['site'] = parameters['site'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Node_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - Name of the Node
-             * @param {string} site_deployment - 
-             * @param {string} site - 
-             * 
-             */
-            xos.prototype.Node_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/nodes/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['site_deployment'] !== undefined) {
-                    form['site_deployment'] = parameters['site_deployment'];
-                }
-
-                if (parameters['site'] !== undefined) {
-                    form['site'] = parameters['site'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Node_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Node_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/nodes/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Dashboard_View_List_GET
-             * 
-             */
-            xos.prototype.Dashboard_View_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/dashboardviews/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Dashboard_View_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - Name of the View
-             * @param {string} url - URL of Dashboard
-             * @param {boolean} enabled - 
-             * 
-             */
-            xos.prototype.Dashboard_View_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/dashboardviews/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url'] !== undefined) {
-                    form['url'] = parameters['url'];
-                }
-
-                if (parameters['url'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Dashboard_View_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Dashboard_View_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/dashboardviews/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Dashboard_View_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - Name of the View
-             * @param {string} url - URL of Dashboard
-             * @param {boolean} enabled - 
-             * 
-             */
-            xos.prototype.Dashboard_View_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/dashboardviews/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url'] !== undefined) {
-                    form['url'] = parameters['url'];
-                }
-
-                if (parameters['url'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Dashboard_View_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - Name of the View
-             * @param {string} url - URL of Dashboard
-             * @param {boolean} enabled - 
-             * 
-             */
-            xos.prototype.Dashboard_View_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/dashboardviews/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['url'] !== undefined) {
-                    form['url'] = parameters['url'];
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Dashboard_View_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Dashboard_View_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/dashboardviews/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Network_List_GET
-             * 
-             */
-            xos.prototype.Controller_Network_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllernetworks/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Network_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} network - 
-             * @param {string} controller - 
-             * @param {string} net_id - Quantum network
-             * @param {string} router_id - Quantum router id
-             * @param {string} subnet_id - Quantum subnet id
-             * @param {string} subnet - 
-             * 
-             */
-            xos.prototype.Controller_Network_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllernetworks/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['network'] !== undefined) {
-                    form['network'] = parameters['network'];
-                }
-
-                if (parameters['network'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: network'));
-                    return deferred.promise;
-                }
-
-                if (parameters['controller'] !== undefined) {
-                    form['controller'] = parameters['controller'];
-                }
-
-                if (parameters['controller'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: controller'));
-                    return deferred.promise;
-                }
-
-                if (parameters['net_id'] !== undefined) {
-                    form['net_id'] = parameters['net_id'];
-                }
-
-                if (parameters['router_id'] !== undefined) {
-                    form['router_id'] = parameters['router_id'];
-                }
-
-                if (parameters['subnet_id'] !== undefined) {
-                    form['subnet_id'] = parameters['subnet_id'];
-                }
-
-                if (parameters['subnet'] !== undefined) {
-                    form['subnet'] = parameters['subnet'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Network_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Controller_Network_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllernetworks/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Network_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} network - 
-             * @param {string} controller - 
-             * @param {string} net_id - Quantum network
-             * @param {string} router_id - Quantum router id
-             * @param {string} subnet_id - Quantum subnet id
-             * @param {string} subnet - 
-             * 
-             */
-            xos.prototype.Controller_Network_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllernetworks/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['network'] !== undefined) {
-                    form['network'] = parameters['network'];
-                }
-
-                if (parameters['network'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: network'));
-                    return deferred.promise;
-                }
-
-                if (parameters['controller'] !== undefined) {
-                    form['controller'] = parameters['controller'];
-                }
-
-                if (parameters['controller'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: controller'));
-                    return deferred.promise;
-                }
-
-                if (parameters['net_id'] !== undefined) {
-                    form['net_id'] = parameters['net_id'];
-                }
-
-                if (parameters['router_id'] !== undefined) {
-                    form['router_id'] = parameters['router_id'];
-                }
-
-                if (parameters['subnet_id'] !== undefined) {
-                    form['subnet_id'] = parameters['subnet_id'];
-                }
-
-                if (parameters['subnet'] !== undefined) {
-                    form['subnet'] = parameters['subnet'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Network_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} network - 
-             * @param {string} controller - 
-             * @param {string} net_id - Quantum network
-             * @param {string} router_id - Quantum router id
-             * @param {string} subnet_id - Quantum subnet id
-             * @param {string} subnet - 
-             * 
-             */
-            xos.prototype.Controller_Network_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllernetworks/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['network'] !== undefined) {
-                    form['network'] = parameters['network'];
-                }
-
-                if (parameters['controller'] !== undefined) {
-                    form['controller'] = parameters['controller'];
-                }
-
-                if (parameters['net_id'] !== undefined) {
-                    form['net_id'] = parameters['net_id'];
-                }
-
-                if (parameters['router_id'] !== undefined) {
-                    form['router_id'] = parameters['router_id'];
-                }
-
-                if (parameters['subnet_id'] !== undefined) {
-                    form['subnet_id'] = parameters['subnet_id'];
-                }
-
-                if (parameters['subnet'] !== undefined) {
-                    form['subnet'] = parameters['subnet'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Network_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Controller_Network_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllernetworks/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Image_Deployments_List_GET
-             * 
-             */
-            xos.prototype.Image_Deployments_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/imagedeploymentses/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Image_Deployments_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} image - 
-             * @param {string} deployment - 
-             * 
-             */
-            xos.prototype.Image_Deployments_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/imagedeploymentses/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['image'] !== undefined) {
-                    form['image'] = parameters['image'];
-                }
-
-                if (parameters['image'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: image'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deployment'] !== undefined) {
-                    form['deployment'] = parameters['deployment'];
-                }
-
-                if (parameters['deployment'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: deployment'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Image_Deployments_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Image_Deployments_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/imagedeploymentses/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Image_Deployments_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} image - 
-             * @param {string} deployment - 
-             * 
-             */
-            xos.prototype.Image_Deployments_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/imagedeploymentses/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['image'] !== undefined) {
-                    form['image'] = parameters['image'];
-                }
-
-                if (parameters['image'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: image'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deployment'] !== undefined) {
-                    form['deployment'] = parameters['deployment'];
-                }
-
-                if (parameters['deployment'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: deployment'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Image_Deployments_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} image - 
-             * @param {string} deployment - 
-             * 
-             */
-            xos.prototype.Image_Deployments_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/imagedeploymentses/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['image'] !== undefined) {
-                    form['image'] = parameters['image'];
-                }
-
-                if (parameters['deployment'] !== undefined) {
-                    form['deployment'] = parameters['deployment'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Image_Deployments_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Image_Deployments_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/imagedeploymentses/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_User_List_GET
-             * 
-             */
-            xos.prototype.Controller_User_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllerusers/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_User_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} user - 
-             * @param {string} controller - 
-             * @param {string} kuser_id - Keystone user id
-             * 
-             */
-            xos.prototype.Controller_User_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllerusers/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['user'] !== undefined) {
-                    form['user'] = parameters['user'];
-                }
-
-                if (parameters['user'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: user'));
-                    return deferred.promise;
-                }
-
-                if (parameters['controller'] !== undefined) {
-                    form['controller'] = parameters['controller'];
-                }
-
-                if (parameters['controller'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: controller'));
-                    return deferred.promise;
-                }
-
-                if (parameters['kuser_id'] !== undefined) {
-                    form['kuser_id'] = parameters['kuser_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_User_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Controller_User_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllerusers/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_User_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} user - 
-             * @param {string} controller - 
-             * @param {string} kuser_id - Keystone user id
-             * 
-             */
-            xos.prototype.Controller_User_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllerusers/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['user'] !== undefined) {
-                    form['user'] = parameters['user'];
-                }
-
-                if (parameters['user'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: user'));
-                    return deferred.promise;
-                }
-
-                if (parameters['controller'] !== undefined) {
-                    form['controller'] = parameters['controller'];
-                }
-
-                if (parameters['controller'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: controller'));
-                    return deferred.promise;
-                }
-
-                if (parameters['kuser_id'] !== undefined) {
-                    form['kuser_id'] = parameters['kuser_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_User_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} user - 
-             * @param {string} controller - 
-             * @param {string} kuser_id - Keystone user id
-             * 
-             */
-            xos.prototype.Controller_User_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllerusers/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['user'] !== undefined) {
-                    form['user'] = parameters['user'];
-                }
-
-                if (parameters['controller'] !== undefined) {
-                    form['controller'] = parameters['controller'];
-                }
-
-                if (parameters['kuser_id'] !== undefined) {
-                    form['kuser_id'] = parameters['kuser_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_User_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Controller_User_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllerusers/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Reserved_Resource_List_GET
-             * 
-             */
-            xos.prototype.Reserved_Resource_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/reservedresources/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Reserved_Resource_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} instance - 
-             * @param {string} resource - 
-             * @param {integer} quantity - 
-             * @param {string} reservationSet - 
-             * 
-             */
-            xos.prototype.Reserved_Resource_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/reservedresources/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['instance'] !== undefined) {
-                    form['instance'] = parameters['instance'];
-                }
-
-                if (parameters['instance'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: instance'));
-                    return deferred.promise;
-                }
-
-                if (parameters['resource'] !== undefined) {
-                    form['resource'] = parameters['resource'];
-                }
-
-                if (parameters['resource'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: resource'));
-                    return deferred.promise;
-                }
-
-                if (parameters['quantity'] !== undefined) {
-                    form['quantity'] = parameters['quantity'];
-                }
-
-                if (parameters['quantity'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: quantity'));
-                    return deferred.promise;
-                }
-
-                if (parameters['reservationSet'] !== undefined) {
-                    form['reservationSet'] = parameters['reservationSet'];
-                }
-
-                if (parameters['reservationSet'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: reservationSet'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Reserved_Resource_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Reserved_Resource_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/reservedresources/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Reserved_Resource_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} instance - 
-             * @param {string} resource - 
-             * @param {integer} quantity - 
-             * @param {string} reservationSet - 
-             * 
-             */
-            xos.prototype.Reserved_Resource_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/reservedresources/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['instance'] !== undefined) {
-                    form['instance'] = parameters['instance'];
-                }
-
-                if (parameters['instance'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: instance'));
-                    return deferred.promise;
-                }
-
-                if (parameters['resource'] !== undefined) {
-                    form['resource'] = parameters['resource'];
-                }
-
-                if (parameters['resource'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: resource'));
-                    return deferred.promise;
-                }
-
-                if (parameters['quantity'] !== undefined) {
-                    form['quantity'] = parameters['quantity'];
-                }
-
-                if (parameters['quantity'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: quantity'));
-                    return deferred.promise;
-                }
-
-                if (parameters['reservationSet'] !== undefined) {
-                    form['reservationSet'] = parameters['reservationSet'];
-                }
-
-                if (parameters['reservationSet'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: reservationSet'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Reserved_Resource_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} instance - 
-             * @param {string} resource - 
-             * @param {integer} quantity - 
-             * @param {string} reservationSet - 
-             * 
-             */
-            xos.prototype.Reserved_Resource_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/reservedresources/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['instance'] !== undefined) {
-                    form['instance'] = parameters['instance'];
-                }
-
-                if (parameters['resource'] !== undefined) {
-                    form['resource'] = parameters['resource'];
-                }
-
-                if (parameters['quantity'] !== undefined) {
-                    form['quantity'] = parameters['quantity'];
-                }
-
-                if (parameters['reservationSet'] !== undefined) {
-                    form['reservationSet'] = parameters['reservationSet'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Reserved_Resource_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Reserved_Resource_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/reservedresources/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Network_Template_List_GET
-             * 
-             */
-            xos.prototype.Network_Template_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/networktemplates/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Network_Template_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - 
-             * @param {string} description - 
-             * @param {integer} guaranteed_bandwidth - 
-             * @param {choice} visibility - 
-             * @param {choice} translation - 
-             * @param {string} shared_network_name - 
-             * @param {string} shared_network_id - Quantum network
-             * @param {choice} topology_kind - 
-             * @param {choice} controller_kind - 
-             * 
-             */
-            xos.prototype.Network_Template_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/networktemplates/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['guaranteed_bandwidth'] !== undefined) {
-                    form['guaranteed_bandwidth'] = parameters['guaranteed_bandwidth'];
-                }
-
-                if (parameters['guaranteed_bandwidth'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: guaranteed_bandwidth'));
-                    return deferred.promise;
-                }
-
-                if (parameters['visibility'] !== undefined) {
-                    form['visibility'] = parameters['visibility'];
-                }
-
-                if (parameters['visibility'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: visibility'));
-                    return deferred.promise;
-                }
-
-                if (parameters['translation'] !== undefined) {
-                    form['translation'] = parameters['translation'];
-                }
-
-                if (parameters['translation'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: translation'));
-                    return deferred.promise;
-                }
-
-                if (parameters['shared_network_name'] !== undefined) {
-                    form['shared_network_name'] = parameters['shared_network_name'];
-                }
-
-                if (parameters['shared_network_id'] !== undefined) {
-                    form['shared_network_id'] = parameters['shared_network_id'];
-                }
-
-                if (parameters['topology_kind'] !== undefined) {
-                    form['topology_kind'] = parameters['topology_kind'];
-                }
-
-                if (parameters['topology_kind'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: topology_kind'));
-                    return deferred.promise;
-                }
-
-                if (parameters['controller_kind'] !== undefined) {
-                    form['controller_kind'] = parameters['controller_kind'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Network_Template_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Network_Template_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/networktemplates/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Network_Template_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - 
-             * @param {string} description - 
-             * @param {integer} guaranteed_bandwidth - 
-             * @param {choice} visibility - 
-             * @param {choice} translation - 
-             * @param {string} shared_network_name - 
-             * @param {string} shared_network_id - Quantum network
-             * @param {choice} topology_kind - 
-             * @param {choice} controller_kind - 
-             * 
-             */
-            xos.prototype.Network_Template_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/networktemplates/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['guaranteed_bandwidth'] !== undefined) {
-                    form['guaranteed_bandwidth'] = parameters['guaranteed_bandwidth'];
-                }
-
-                if (parameters['guaranteed_bandwidth'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: guaranteed_bandwidth'));
-                    return deferred.promise;
-                }
-
-                if (parameters['visibility'] !== undefined) {
-                    form['visibility'] = parameters['visibility'];
-                }
-
-                if (parameters['visibility'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: visibility'));
-                    return deferred.promise;
-                }
-
-                if (parameters['translation'] !== undefined) {
-                    form['translation'] = parameters['translation'];
-                }
-
-                if (parameters['translation'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: translation'));
-                    return deferred.promise;
-                }
-
-                if (parameters['shared_network_name'] !== undefined) {
-                    form['shared_network_name'] = parameters['shared_network_name'];
-                }
-
-                if (parameters['shared_network_id'] !== undefined) {
-                    form['shared_network_id'] = parameters['shared_network_id'];
-                }
-
-                if (parameters['topology_kind'] !== undefined) {
-                    form['topology_kind'] = parameters['topology_kind'];
-                }
-
-                if (parameters['topology_kind'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: topology_kind'));
-                    return deferred.promise;
-                }
-
-                if (parameters['controller_kind'] !== undefined) {
-                    form['controller_kind'] = parameters['controller_kind'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Network_Template_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - 
-             * @param {string} description - 
-             * @param {integer} guaranteed_bandwidth - 
-             * @param {choice} visibility - 
-             * @param {choice} translation - 
-             * @param {string} shared_network_name - 
-             * @param {string} shared_network_id - Quantum network
-             * @param {choice} topology_kind - 
-             * @param {choice} controller_kind - 
-             * 
-             */
-            xos.prototype.Network_Template_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/networktemplates/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['guaranteed_bandwidth'] !== undefined) {
-                    form['guaranteed_bandwidth'] = parameters['guaranteed_bandwidth'];
-                }
-
-                if (parameters['visibility'] !== undefined) {
-                    form['visibility'] = parameters['visibility'];
-                }
-
-                if (parameters['translation'] !== undefined) {
-                    form['translation'] = parameters['translation'];
-                }
-
-                if (parameters['shared_network_name'] !== undefined) {
-                    form['shared_network_name'] = parameters['shared_network_name'];
-                }
-
-                if (parameters['shared_network_id'] !== undefined) {
-                    form['shared_network_id'] = parameters['shared_network_id'];
-                }
-
-                if (parameters['topology_kind'] !== undefined) {
-                    form['topology_kind'] = parameters['topology_kind'];
-                }
-
-                if (parameters['controller_kind'] !== undefined) {
-                    form['controller_kind'] = parameters['controller_kind'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Network_Template_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Network_Template_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/networktemplates/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Network_Slice_List_GET
-             * 
-             */
-            xos.prototype.Network_Slice_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/networkslices/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Network_Slice_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} network - 
-             * @param {string} slice - 
-             * 
-             */
-            xos.prototype.Network_Slice_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/networkslices/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['network'] !== undefined) {
-                    form['network'] = parameters['network'];
-                }
-
-                if (parameters['network'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: network'));
-                    return deferred.promise;
-                }
-
-                if (parameters['slice'] !== undefined) {
-                    form['slice'] = parameters['slice'];
-                }
-
-                if (parameters['slice'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: slice'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Network_Slice_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Network_Slice_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/networkslices/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Network_Slice_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} network - 
-             * @param {string} slice - 
-             * 
-             */
-            xos.prototype.Network_Slice_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/networkslices/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['network'] !== undefined) {
-                    form['network'] = parameters['network'];
-                }
-
-                if (parameters['network'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: network'));
-                    return deferred.promise;
-                }
-
-                if (parameters['slice'] !== undefined) {
-                    form['slice'] = parameters['slice'];
-                }
-
-                if (parameters['slice'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: slice'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Network_Slice_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} network - 
-             * @param {string} slice - 
-             * 
-             */
-            xos.prototype.Network_Slice_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/networkslices/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['network'] !== undefined) {
-                    form['network'] = parameters['network'];
-                }
-
-                if (parameters['slice'] !== undefined) {
-                    form['slice'] = parameters['slice'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Network_Slice_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Network_Slice_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/networkslices/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#User_Dashboard_View_List_GET
-             * 
-             */
-            xos.prototype.User_Dashboard_View_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/userdashboardviews/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#User_Dashboard_View_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} user - 
-             * @param {string} dashboardView - 
-             * @param {integer} order - 
-             * 
-             */
-            xos.prototype.User_Dashboard_View_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/userdashboardviews/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['user'] !== undefined) {
-                    form['user'] = parameters['user'];
-                }
-
-                if (parameters['user'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: user'));
-                    return deferred.promise;
-                }
-
-                if (parameters['dashboardView'] !== undefined) {
-                    form['dashboardView'] = parameters['dashboardView'];
-                }
-
-                if (parameters['dashboardView'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: dashboardView'));
-                    return deferred.promise;
-                }
-
-                if (parameters['order'] !== undefined) {
-                    form['order'] = parameters['order'];
-                }
-
-                if (parameters['order'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: order'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#User_Dashboard_View_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.User_Dashboard_View_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/userdashboardviews/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#User_Dashboard_View_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} user - 
-             * @param {string} dashboardView - 
-             * @param {integer} order - 
-             * 
-             */
-            xos.prototype.User_Dashboard_View_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/userdashboardviews/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['user'] !== undefined) {
-                    form['user'] = parameters['user'];
-                }
-
-                if (parameters['user'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: user'));
-                    return deferred.promise;
-                }
-
-                if (parameters['dashboardView'] !== undefined) {
-                    form['dashboardView'] = parameters['dashboardView'];
-                }
-
-                if (parameters['dashboardView'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: dashboardView'));
-                    return deferred.promise;
-                }
-
-                if (parameters['order'] !== undefined) {
-                    form['order'] = parameters['order'];
-                }
-
-                if (parameters['order'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: order'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#User_Dashboard_View_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} user - 
-             * @param {string} dashboardView - 
-             * @param {integer} order - 
-             * 
-             */
-            xos.prototype.User_Dashboard_View_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/userdashboardviews/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['user'] !== undefined) {
-                    form['user'] = parameters['user'];
-                }
-
-                if (parameters['dashboardView'] !== undefined) {
-                    form['dashboardView'] = parameters['dashboardView'];
-                }
-
-                if (parameters['order'] !== undefined) {
-                    form['order'] = parameters['order'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#User_Dashboard_View_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.User_Dashboard_View_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/userdashboardviews/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_List_GET
-             * 
-             */
-            xos.prototype.Controller_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllers/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - Name of the Controller
-             * @param {string} backend_type - Type of compute controller, e.g. EC2, OpenStack, or OpenStack version
-             * @param {string} version - Controller version
-             * @param {string} auth_url - Auth url for the compute controller
-             * @param {string} admin_user - Username of an admin user at this controller
-             * @param {string} admin_password - Password of theadmin user at this controller
-             * @param {string} admin_tenant - Name of the tenant the admin user belongs to
-             * @param {string} domain - Name of the domain this controller belongs to
-             * @param {string} rabbit_host - IP address of rabbitmq server at this controller
-             * @param {string} rabbit_user - Username of rabbitmq server at this controller
-             * @param {string} rabbit_password - Password of rabbitmq server at this controller
-             * @param {string} deployment - 
-             * 
-             */
-            xos.prototype.Controller_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllers/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['backend_type'] !== undefined) {
-                    form['backend_type'] = parameters['backend_type'];
-                }
-
-                if (parameters['backend_type'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_type'));
-                    return deferred.promise;
-                }
-
-                if (parameters['version'] !== undefined) {
-                    form['version'] = parameters['version'];
-                }
-
-                if (parameters['version'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: version'));
-                    return deferred.promise;
-                }
-
-                if (parameters['auth_url'] !== undefined) {
-                    form['auth_url'] = parameters['auth_url'];
-                }
-
-                if (parameters['admin_user'] !== undefined) {
-                    form['admin_user'] = parameters['admin_user'];
-                }
-
-                if (parameters['admin_password'] !== undefined) {
-                    form['admin_password'] = parameters['admin_password'];
-                }
-
-                if (parameters['admin_tenant'] !== undefined) {
-                    form['admin_tenant'] = parameters['admin_tenant'];
-                }
-
-                if (parameters['domain'] !== undefined) {
-                    form['domain'] = parameters['domain'];
-                }
-
-                if (parameters['rabbit_host'] !== undefined) {
-                    form['rabbit_host'] = parameters['rabbit_host'];
-                }
-
-                if (parameters['rabbit_user'] !== undefined) {
-                    form['rabbit_user'] = parameters['rabbit_user'];
-                }
-
-                if (parameters['rabbit_password'] !== undefined) {
-                    form['rabbit_password'] = parameters['rabbit_password'];
-                }
-
-                if (parameters['deployment'] !== undefined) {
-                    form['deployment'] = parameters['deployment'];
-                }
-
-                if (parameters['deployment'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: deployment'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Controller_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllers/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - Name of the Controller
-             * @param {string} backend_type - Type of compute controller, e.g. EC2, OpenStack, or OpenStack version
-             * @param {string} version - Controller version
-             * @param {string} auth_url - Auth url for the compute controller
-             * @param {string} admin_user - Username of an admin user at this controller
-             * @param {string} admin_password - Password of theadmin user at this controller
-             * @param {string} admin_tenant - Name of the tenant the admin user belongs to
-             * @param {string} domain - Name of the domain this controller belongs to
-             * @param {string} rabbit_host - IP address of rabbitmq server at this controller
-             * @param {string} rabbit_user - Username of rabbitmq server at this controller
-             * @param {string} rabbit_password - Password of rabbitmq server at this controller
-             * @param {string} deployment - 
-             * 
-             */
-            xos.prototype.Controller_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllers/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['backend_type'] !== undefined) {
-                    form['backend_type'] = parameters['backend_type'];
-                }
-
-                if (parameters['backend_type'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_type'));
-                    return deferred.promise;
-                }
-
-                if (parameters['version'] !== undefined) {
-                    form['version'] = parameters['version'];
-                }
-
-                if (parameters['version'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: version'));
-                    return deferred.promise;
-                }
-
-                if (parameters['auth_url'] !== undefined) {
-                    form['auth_url'] = parameters['auth_url'];
-                }
-
-                if (parameters['admin_user'] !== undefined) {
-                    form['admin_user'] = parameters['admin_user'];
-                }
-
-                if (parameters['admin_password'] !== undefined) {
-                    form['admin_password'] = parameters['admin_password'];
-                }
-
-                if (parameters['admin_tenant'] !== undefined) {
-                    form['admin_tenant'] = parameters['admin_tenant'];
-                }
-
-                if (parameters['domain'] !== undefined) {
-                    form['domain'] = parameters['domain'];
-                }
-
-                if (parameters['rabbit_host'] !== undefined) {
-                    form['rabbit_host'] = parameters['rabbit_host'];
-                }
-
-                if (parameters['rabbit_user'] !== undefined) {
-                    form['rabbit_user'] = parameters['rabbit_user'];
-                }
-
-                if (parameters['rabbit_password'] !== undefined) {
-                    form['rabbit_password'] = parameters['rabbit_password'];
-                }
-
-                if (parameters['deployment'] !== undefined) {
-                    form['deployment'] = parameters['deployment'];
-                }
-
-                if (parameters['deployment'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: deployment'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - Name of the Controller
-             * @param {string} backend_type - Type of compute controller, e.g. EC2, OpenStack, or OpenStack version
-             * @param {string} version - Controller version
-             * @param {string} auth_url - Auth url for the compute controller
-             * @param {string} admin_user - Username of an admin user at this controller
-             * @param {string} admin_password - Password of theadmin user at this controller
-             * @param {string} admin_tenant - Name of the tenant the admin user belongs to
-             * @param {string} domain - Name of the domain this controller belongs to
-             * @param {string} rabbit_host - IP address of rabbitmq server at this controller
-             * @param {string} rabbit_user - Username of rabbitmq server at this controller
-             * @param {string} rabbit_password - Password of rabbitmq server at this controller
-             * @param {string} deployment - 
-             * 
-             */
-            xos.prototype.Controller_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllers/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['backend_type'] !== undefined) {
-                    form['backend_type'] = parameters['backend_type'];
-                }
-
-                if (parameters['version'] !== undefined) {
-                    form['version'] = parameters['version'];
-                }
-
-                if (parameters['auth_url'] !== undefined) {
-                    form['auth_url'] = parameters['auth_url'];
-                }
-
-                if (parameters['admin_user'] !== undefined) {
-                    form['admin_user'] = parameters['admin_user'];
-                }
-
-                if (parameters['admin_password'] !== undefined) {
-                    form['admin_password'] = parameters['admin_password'];
-                }
-
-                if (parameters['admin_tenant'] !== undefined) {
-                    form['admin_tenant'] = parameters['admin_tenant'];
-                }
-
-                if (parameters['domain'] !== undefined) {
-                    form['domain'] = parameters['domain'];
-                }
-
-                if (parameters['rabbit_host'] !== undefined) {
-                    form['rabbit_host'] = parameters['rabbit_host'];
-                }
-
-                if (parameters['rabbit_user'] !== undefined) {
-                    form['rabbit_user'] = parameters['rabbit_user'];
-                }
-
-                if (parameters['rabbit_password'] !== undefined) {
-                    form['rabbit_password'] = parameters['rabbit_password'];
-                }
-
-                if (parameters['deployment'] !== undefined) {
-                    form['deployment'] = parameters['deployment'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Controller_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllers/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#User_List_GET
-             * 
-             */
-            xos.prototype.User_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/users/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#User_List_POST
-             * @param {string} password - 
-             * @param {string} last_login - 
-             * @param {string} email - 
-             * @param {string} username - 
-             * @param {string} firstname - person's given name
-             * @param {string} lastname - person's surname
-             * @param {string} phone - phone number contact
-             * @param {string} user_url - 
-             * @param {string} site - Site this user will be homed too
-             * @param {string} public_key - Public key string
-             * @param {boolean} is_active - 
-             * @param {boolean} is_admin - 
-             * @param {boolean} is_staff - 
-             * @param {boolean} is_readonly - 
-             * @param {boolean} is_registering - 
-             * @param {boolean} is_appuser - 
-             * @param {string} login_page - send this user to a specific page on login
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {choice} timezone - 
-             * 
-             */
-            xos.prototype.User_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/users/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['password'] !== undefined) {
-                    form['password'] = parameters['password'];
-                }
-
-                if (parameters['password'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: password'));
-                    return deferred.promise;
-                }
-
-                if (parameters['last_login'] !== undefined) {
-                    form['last_login'] = parameters['last_login'];
-                }
-
-                if (parameters['last_login'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: last_login'));
-                    return deferred.promise;
-                }
-
-                if (parameters['email'] !== undefined) {
-                    form['email'] = parameters['email'];
-                }
-
-                if (parameters['email'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: email'));
-                    return deferred.promise;
-                }
-
-                if (parameters['username'] !== undefined) {
-                    form['username'] = parameters['username'];
-                }
-
-                if (parameters['username'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: username'));
-                    return deferred.promise;
-                }
-
-                if (parameters['firstname'] !== undefined) {
-                    form['firstname'] = parameters['firstname'];
-                }
-
-                if (parameters['firstname'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: firstname'));
-                    return deferred.promise;
-                }
-
-                if (parameters['lastname'] !== undefined) {
-                    form['lastname'] = parameters['lastname'];
-                }
-
-                if (parameters['lastname'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: lastname'));
-                    return deferred.promise;
-                }
-
-                if (parameters['phone'] !== undefined) {
-                    form['phone'] = parameters['phone'];
-                }
-
-                if (parameters['user_url'] !== undefined) {
-                    form['user_url'] = parameters['user_url'];
-                }
-
-                if (parameters['site'] !== undefined) {
-                    form['site'] = parameters['site'];
-                }
-
-                if (parameters['site'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: site'));
-                    return deferred.promise;
-                }
-
-                if (parameters['public_key'] !== undefined) {
-                    form['public_key'] = parameters['public_key'];
-                }
-
-                if (parameters['is_active'] !== undefined) {
-                    form['is_active'] = parameters['is_active'];
-                }
-
-                if (parameters['is_admin'] !== undefined) {
-                    form['is_admin'] = parameters['is_admin'];
-                }
-
-                if (parameters['is_staff'] !== undefined) {
-                    form['is_staff'] = parameters['is_staff'];
-                }
-
-                if (parameters['is_readonly'] !== undefined) {
-                    form['is_readonly'] = parameters['is_readonly'];
-                }
-
-                if (parameters['is_registering'] !== undefined) {
-                    form['is_registering'] = parameters['is_registering'];
-                }
-
-                if (parameters['is_appuser'] !== undefined) {
-                    form['is_appuser'] = parameters['is_appuser'];
-                }
-
-                if (parameters['login_page'] !== undefined) {
-                    form['login_page'] = parameters['login_page'];
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['timezone'] !== undefined) {
-                    form['timezone'] = parameters['timezone'];
-                }
-
-                if (parameters['timezone'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: timezone'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#User_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.User_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/users/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#User_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} password - 
-             * @param {string} last_login - 
-             * @param {string} email - 
-             * @param {string} username - 
-             * @param {string} firstname - person's given name
-             * @param {string} lastname - person's surname
-             * @param {string} phone - phone number contact
-             * @param {string} user_url - 
-             * @param {string} site - Site this user will be homed too
-             * @param {string} public_key - Public key string
-             * @param {boolean} is_active - 
-             * @param {boolean} is_admin - 
-             * @param {boolean} is_staff - 
-             * @param {boolean} is_readonly - 
-             * @param {boolean} is_registering - 
-             * @param {boolean} is_appuser - 
-             * @param {string} login_page - send this user to a specific page on login
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {choice} timezone - 
-             * 
-             */
-            xos.prototype.User_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/users/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['password'] !== undefined) {
-                    form['password'] = parameters['password'];
-                }
-
-                if (parameters['password'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: password'));
-                    return deferred.promise;
-                }
-
-                if (parameters['last_login'] !== undefined) {
-                    form['last_login'] = parameters['last_login'];
-                }
-
-                if (parameters['last_login'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: last_login'));
-                    return deferred.promise;
-                }
-
-                if (parameters['email'] !== undefined) {
-                    form['email'] = parameters['email'];
-                }
-
-                if (parameters['email'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: email'));
-                    return deferred.promise;
-                }
-
-                if (parameters['username'] !== undefined) {
-                    form['username'] = parameters['username'];
-                }
-
-                if (parameters['username'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: username'));
-                    return deferred.promise;
-                }
-
-                if (parameters['firstname'] !== undefined) {
-                    form['firstname'] = parameters['firstname'];
-                }
-
-                if (parameters['firstname'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: firstname'));
-                    return deferred.promise;
-                }
-
-                if (parameters['lastname'] !== undefined) {
-                    form['lastname'] = parameters['lastname'];
-                }
-
-                if (parameters['lastname'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: lastname'));
-                    return deferred.promise;
-                }
-
-                if (parameters['phone'] !== undefined) {
-                    form['phone'] = parameters['phone'];
-                }
-
-                if (parameters['user_url'] !== undefined) {
-                    form['user_url'] = parameters['user_url'];
-                }
-
-                if (parameters['site'] !== undefined) {
-                    form['site'] = parameters['site'];
-                }
-
-                if (parameters['site'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: site'));
-                    return deferred.promise;
-                }
-
-                if (parameters['public_key'] !== undefined) {
-                    form['public_key'] = parameters['public_key'];
-                }
-
-                if (parameters['is_active'] !== undefined) {
-                    form['is_active'] = parameters['is_active'];
-                }
-
-                if (parameters['is_admin'] !== undefined) {
-                    form['is_admin'] = parameters['is_admin'];
-                }
-
-                if (parameters['is_staff'] !== undefined) {
-                    form['is_staff'] = parameters['is_staff'];
-                }
-
-                if (parameters['is_readonly'] !== undefined) {
-                    form['is_readonly'] = parameters['is_readonly'];
-                }
-
-                if (parameters['is_registering'] !== undefined) {
-                    form['is_registering'] = parameters['is_registering'];
-                }
-
-                if (parameters['is_appuser'] !== undefined) {
-                    form['is_appuser'] = parameters['is_appuser'];
-                }
-
-                if (parameters['login_page'] !== undefined) {
-                    form['login_page'] = parameters['login_page'];
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['timezone'] !== undefined) {
-                    form['timezone'] = parameters['timezone'];
-                }
-
-                if (parameters['timezone'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: timezone'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#User_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} password - 
-             * @param {string} last_login - 
-             * @param {string} email - 
-             * @param {string} username - 
-             * @param {string} firstname - person's given name
-             * @param {string} lastname - person's surname
-             * @param {string} phone - phone number contact
-             * @param {string} user_url - 
-             * @param {string} site - Site this user will be homed too
-             * @param {string} public_key - Public key string
-             * @param {boolean} is_active - 
-             * @param {boolean} is_admin - 
-             * @param {boolean} is_staff - 
-             * @param {boolean} is_readonly - 
-             * @param {boolean} is_registering - 
-             * @param {boolean} is_appuser - 
-             * @param {string} login_page - send this user to a specific page on login
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {choice} timezone - 
-             * 
-             */
-            xos.prototype.User_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/users/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['password'] !== undefined) {
-                    form['password'] = parameters['password'];
-                }
-
-                if (parameters['last_login'] !== undefined) {
-                    form['last_login'] = parameters['last_login'];
-                }
-
-                if (parameters['email'] !== undefined) {
-                    form['email'] = parameters['email'];
-                }
-
-                if (parameters['username'] !== undefined) {
-                    form['username'] = parameters['username'];
-                }
-
-                if (parameters['firstname'] !== undefined) {
-                    form['firstname'] = parameters['firstname'];
-                }
-
-                if (parameters['lastname'] !== undefined) {
-                    form['lastname'] = parameters['lastname'];
-                }
-
-                if (parameters['phone'] !== undefined) {
-                    form['phone'] = parameters['phone'];
-                }
-
-                if (parameters['user_url'] !== undefined) {
-                    form['user_url'] = parameters['user_url'];
-                }
-
-                if (parameters['site'] !== undefined) {
-                    form['site'] = parameters['site'];
-                }
-
-                if (parameters['public_key'] !== undefined) {
-                    form['public_key'] = parameters['public_key'];
-                }
-
-                if (parameters['is_active'] !== undefined) {
-                    form['is_active'] = parameters['is_active'];
-                }
-
-                if (parameters['is_admin'] !== undefined) {
-                    form['is_admin'] = parameters['is_admin'];
-                }
-
-                if (parameters['is_staff'] !== undefined) {
-                    form['is_staff'] = parameters['is_staff'];
-                }
-
-                if (parameters['is_readonly'] !== undefined) {
-                    form['is_readonly'] = parameters['is_readonly'];
-                }
-
-                if (parameters['is_registering'] !== undefined) {
-                    form['is_registering'] = parameters['is_registering'];
-                }
-
-                if (parameters['is_appuser'] !== undefined) {
-                    form['is_appuser'] = parameters['is_appuser'];
-                }
-
-                if (parameters['login_page'] !== undefined) {
-                    form['login_page'] = parameters['login_page'];
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['timezone'] !== undefined) {
-                    form['timezone'] = parameters['timezone'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#User_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.User_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/users/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Deployment_List_GET
-             * 
-             */
-            xos.prototype.Deployment_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/deployments/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Deployment_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - Name of the Deployment
-             * @param {string} accessControl - Access control list that specifies which sites/users may use nodes in this deployment
-             * 
-             */
-            xos.prototype.Deployment_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/deployments/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['accessControl'] !== undefined) {
-                    form['accessControl'] = parameters['accessControl'];
-                }
-
-                if (parameters['accessControl'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: accessControl'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Deployment_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Deployment_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/deployments/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Deployment_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - Name of the Deployment
-             * @param {string} accessControl - Access control list that specifies which sites/users may use nodes in this deployment
-             * 
-             */
-            xos.prototype.Deployment_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/deployments/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['accessControl'] !== undefined) {
-                    form['accessControl'] = parameters['accessControl'];
-                }
-
-                if (parameters['accessControl'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: accessControl'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Deployment_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - Name of the Deployment
-             * @param {string} accessControl - Access control list that specifies which sites/users may use nodes in this deployment
-             * 
-             */
-            xos.prototype.Deployment_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/deployments/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['accessControl'] !== undefined) {
-                    form['accessControl'] = parameters['accessControl'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Deployment_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Deployment_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/deployments/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Reservation_List_GET
-             * 
-             */
-            xos.prototype.Reservation_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/reservations/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Reservation_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} startTime - 
-             * @param {string} slice - 
-             * @param {integer} duration - 
-             * 
-             */
-            xos.prototype.Reservation_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/reservations/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['startTime'] !== undefined) {
-                    form['startTime'] = parameters['startTime'];
-                }
-
-                if (parameters['startTime'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: startTime'));
-                    return deferred.promise;
-                }
-
-                if (parameters['slice'] !== undefined) {
-                    form['slice'] = parameters['slice'];
-                }
-
-                if (parameters['slice'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: slice'));
-                    return deferred.promise;
-                }
-
-                if (parameters['duration'] !== undefined) {
-                    form['duration'] = parameters['duration'];
-                }
-
-                if (parameters['duration'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: duration'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Reservation_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Reservation_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/reservations/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Reservation_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} startTime - 
-             * @param {string} slice - 
-             * @param {integer} duration - 
-             * 
-             */
-            xos.prototype.Reservation_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/reservations/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['startTime'] !== undefined) {
-                    form['startTime'] = parameters['startTime'];
-                }
-
-                if (parameters['startTime'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: startTime'));
-                    return deferred.promise;
-                }
-
-                if (parameters['slice'] !== undefined) {
-                    form['slice'] = parameters['slice'];
-                }
-
-                if (parameters['slice'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: slice'));
-                    return deferred.promise;
-                }
-
-                if (parameters['duration'] !== undefined) {
-                    form['duration'] = parameters['duration'];
-                }
-
-                if (parameters['duration'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: duration'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Reservation_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} startTime - 
-             * @param {string} slice - 
-             * @param {integer} duration - 
-             * 
-             */
-            xos.prototype.Reservation_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/reservations/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['startTime'] !== undefined) {
-                    form['startTime'] = parameters['startTime'];
-                }
-
-                if (parameters['slice'] !== undefined) {
-                    form['slice'] = parameters['slice'];
-                }
-
-                if (parameters['duration'] !== undefined) {
-                    form['duration'] = parameters['duration'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Reservation_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Reservation_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/reservations/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Site_Privilege_List_GET
-             * 
-             */
-            xos.prototype.Site_Privilege_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/siteprivileges/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Site_Privilege_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} user - 
-             * @param {string} site - 
-             * @param {string} role - 
-             * 
-             */
-            xos.prototype.Site_Privilege_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/siteprivileges/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['user'] !== undefined) {
-                    form['user'] = parameters['user'];
-                }
-
-                if (parameters['user'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: user'));
-                    return deferred.promise;
-                }
-
-                if (parameters['site'] !== undefined) {
-                    form['site'] = parameters['site'];
-                }
-
-                if (parameters['site'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: site'));
-                    return deferred.promise;
-                }
-
-                if (parameters['role'] !== undefined) {
-                    form['role'] = parameters['role'];
-                }
-
-                if (parameters['role'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: role'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Site_Privilege_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Site_Privilege_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/siteprivileges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Site_Privilege_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} user - 
-             * @param {string} site - 
-             * @param {string} role - 
-             * 
-             */
-            xos.prototype.Site_Privilege_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/siteprivileges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['user'] !== undefined) {
-                    form['user'] = parameters['user'];
-                }
-
-                if (parameters['user'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: user'));
-                    return deferred.promise;
-                }
-
-                if (parameters['site'] !== undefined) {
-                    form['site'] = parameters['site'];
-                }
-
-                if (parameters['site'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: site'));
-                    return deferred.promise;
-                }
-
-                if (parameters['role'] !== undefined) {
-                    form['role'] = parameters['role'];
-                }
-
-                if (parameters['role'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: role'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Site_Privilege_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} user - 
-             * @param {string} site - 
-             * @param {string} role - 
-             * 
-             */
-            xos.prototype.Site_Privilege_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/siteprivileges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['user'] !== undefined) {
-                    form['user'] = parameters['user'];
-                }
-
-                if (parameters['site'] !== undefined) {
-                    form['site'] = parameters['site'];
-                }
-
-                if (parameters['role'] !== undefined) {
-                    form['role'] = parameters['role'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Site_Privilege_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Site_Privilege_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/siteprivileges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Slice_List_GET
-             * 
-             */
-            xos.prototype.Controller_Slice_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllerslices/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Slice_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} controller - 
-             * @param {string} slice - 
-             * @param {string} tenant_id - Keystone tenant id
-             * 
-             */
-            xos.prototype.Controller_Slice_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllerslices/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['controller'] !== undefined) {
-                    form['controller'] = parameters['controller'];
-                }
-
-                if (parameters['controller'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: controller'));
-                    return deferred.promise;
-                }
-
-                if (parameters['slice'] !== undefined) {
-                    form['slice'] = parameters['slice'];
-                }
-
-                if (parameters['slice'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: slice'));
-                    return deferred.promise;
-                }
-
-                if (parameters['tenant_id'] !== undefined) {
-                    form['tenant_id'] = parameters['tenant_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Slice_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Controller_Slice_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllerslices/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Slice_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} controller - 
-             * @param {string} slice - 
-             * @param {string} tenant_id - Keystone tenant id
-             * 
-             */
-            xos.prototype.Controller_Slice_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllerslices/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['controller'] !== undefined) {
-                    form['controller'] = parameters['controller'];
-                }
-
-                if (parameters['controller'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: controller'));
-                    return deferred.promise;
-                }
-
-                if (parameters['slice'] !== undefined) {
-                    form['slice'] = parameters['slice'];
-                }
-
-                if (parameters['slice'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: slice'));
-                    return deferred.promise;
-                }
-
-                if (parameters['tenant_id'] !== undefined) {
-                    form['tenant_id'] = parameters['tenant_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Slice_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} controller - 
-             * @param {string} slice - 
-             * @param {string} tenant_id - Keystone tenant id
-             * 
-             */
-            xos.prototype.Controller_Slice_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllerslices/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['controller'] !== undefined) {
-                    form['controller'] = parameters['controller'];
-                }
-
-                if (parameters['slice'] !== undefined) {
-                    form['slice'] = parameters['slice'];
-                }
-
-                if (parameters['tenant_id'] !== undefined) {
-                    form['tenant_id'] = parameters['tenant_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Slice_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Controller_Slice_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllerslices/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tenant_List_GET
-             * 
-             */
-            xos.prototype.Tenant_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tenants/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tenant_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} kind - 
-             * @param {string} provider_service - 
-             * @param {string} subscriber_service - 
-             * @param {string} subscriber_tenant - 
-             * @param {string} subscriber_user - 
-             * @param {string} subscriber_root - 
-             * @param {string} service_specific_id - 
-             * @param {string} service_specific_attribute - 
-             * @param {choice} connect_method - 
-             * 
-             */
-            xos.prototype.Tenant_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tenants/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['kind'] !== undefined) {
-                    form['kind'] = parameters['kind'];
-                }
-
-                if (parameters['kind'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: kind'));
-                    return deferred.promise;
-                }
-
-                if (parameters['provider_service'] !== undefined) {
-                    form['provider_service'] = parameters['provider_service'];
-                }
-
-                if (parameters['provider_service'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: provider_service'));
-                    return deferred.promise;
-                }
-
-                if (parameters['subscriber_service'] !== undefined) {
-                    form['subscriber_service'] = parameters['subscriber_service'];
-                }
-
-                if (parameters['subscriber_tenant'] !== undefined) {
-                    form['subscriber_tenant'] = parameters['subscriber_tenant'];
-                }
-
-                if (parameters['subscriber_user'] !== undefined) {
-                    form['subscriber_user'] = parameters['subscriber_user'];
-                }
-
-                if (parameters['subscriber_root'] !== undefined) {
-                    form['subscriber_root'] = parameters['subscriber_root'];
-                }
-
-                if (parameters['service_specific_id'] !== undefined) {
-                    form['service_specific_id'] = parameters['service_specific_id'];
-                }
-
-                if (parameters['service_specific_attribute'] !== undefined) {
-                    form['service_specific_attribute'] = parameters['service_specific_attribute'];
-                }
-
-                if (parameters['connect_method'] !== undefined) {
-                    form['connect_method'] = parameters['connect_method'];
-                }
-
-                if (parameters['connect_method'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: connect_method'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tenant_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Tenant_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tenants/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tenant_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} kind - 
-             * @param {string} provider_service - 
-             * @param {string} subscriber_service - 
-             * @param {string} subscriber_tenant - 
-             * @param {string} subscriber_user - 
-             * @param {string} subscriber_root - 
-             * @param {string} service_specific_id - 
-             * @param {string} service_specific_attribute - 
-             * @param {choice} connect_method - 
-             * 
-             */
-            xos.prototype.Tenant_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tenants/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['kind'] !== undefined) {
-                    form['kind'] = parameters['kind'];
-                }
-
-                if (parameters['kind'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: kind'));
-                    return deferred.promise;
-                }
-
-                if (parameters['provider_service'] !== undefined) {
-                    form['provider_service'] = parameters['provider_service'];
-                }
-
-                if (parameters['provider_service'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: provider_service'));
-                    return deferred.promise;
-                }
-
-                if (parameters['subscriber_service'] !== undefined) {
-                    form['subscriber_service'] = parameters['subscriber_service'];
-                }
-
-                if (parameters['subscriber_tenant'] !== undefined) {
-                    form['subscriber_tenant'] = parameters['subscriber_tenant'];
-                }
-
-                if (parameters['subscriber_user'] !== undefined) {
-                    form['subscriber_user'] = parameters['subscriber_user'];
-                }
-
-                if (parameters['subscriber_root'] !== undefined) {
-                    form['subscriber_root'] = parameters['subscriber_root'];
-                }
-
-                if (parameters['service_specific_id'] !== undefined) {
-                    form['service_specific_id'] = parameters['service_specific_id'];
-                }
-
-                if (parameters['service_specific_attribute'] !== undefined) {
-                    form['service_specific_attribute'] = parameters['service_specific_attribute'];
-                }
-
-                if (parameters['connect_method'] !== undefined) {
-                    form['connect_method'] = parameters['connect_method'];
-                }
-
-                if (parameters['connect_method'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: connect_method'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tenant_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} kind - 
-             * @param {string} provider_service - 
-             * @param {string} subscriber_service - 
-             * @param {string} subscriber_tenant - 
-             * @param {string} subscriber_user - 
-             * @param {string} subscriber_root - 
-             * @param {string} service_specific_id - 
-             * @param {string} service_specific_attribute - 
-             * @param {choice} connect_method - 
-             * 
-             */
-            xos.prototype.Tenant_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tenants/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['kind'] !== undefined) {
-                    form['kind'] = parameters['kind'];
-                }
-
-                if (parameters['provider_service'] !== undefined) {
-                    form['provider_service'] = parameters['provider_service'];
-                }
-
-                if (parameters['subscriber_service'] !== undefined) {
-                    form['subscriber_service'] = parameters['subscriber_service'];
-                }
-
-                if (parameters['subscriber_tenant'] !== undefined) {
-                    form['subscriber_tenant'] = parameters['subscriber_tenant'];
-                }
-
-                if (parameters['subscriber_user'] !== undefined) {
-                    form['subscriber_user'] = parameters['subscriber_user'];
-                }
-
-                if (parameters['subscriber_root'] !== undefined) {
-                    form['subscriber_root'] = parameters['subscriber_root'];
-                }
-
-                if (parameters['service_specific_id'] !== undefined) {
-                    form['service_specific_id'] = parameters['service_specific_id'];
-                }
-
-                if (parameters['service_specific_attribute'] !== undefined) {
-                    form['service_specific_attribute'] = parameters['service_specific_attribute'];
-                }
-
-                if (parameters['connect_method'] !== undefined) {
-                    form['connect_method'] = parameters['connect_method'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tenant_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Tenant_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tenants/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Dashboard_View_List_GET
-             * 
-             */
-            xos.prototype.Controller_Dashboard_View_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllerdashboardviews/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Dashboard_View_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} controller - 
-             * @param {string} dashboardView - 
-             * @param {boolean} enabled - 
-             * @param {string} url - URL of Dashboard
-             * 
-             */
-            xos.prototype.Controller_Dashboard_View_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllerdashboardviews/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['controller'] !== undefined) {
-                    form['controller'] = parameters['controller'];
-                }
-
-                if (parameters['controller'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: controller'));
-                    return deferred.promise;
-                }
-
-                if (parameters['dashboardView'] !== undefined) {
-                    form['dashboardView'] = parameters['dashboardView'];
-                }
-
-                if (parameters['dashboardView'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: dashboardView'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters['url'] !== undefined) {
-                    form['url'] = parameters['url'];
-                }
-
-                if (parameters['url'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Dashboard_View_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Controller_Dashboard_View_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllerdashboardviews/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Dashboard_View_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} controller - 
-             * @param {string} dashboardView - 
-             * @param {boolean} enabled - 
-             * @param {string} url - URL of Dashboard
-             * 
-             */
-            xos.prototype.Controller_Dashboard_View_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllerdashboardviews/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['controller'] !== undefined) {
-                    form['controller'] = parameters['controller'];
-                }
-
-                if (parameters['controller'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: controller'));
-                    return deferred.promise;
-                }
-
-                if (parameters['dashboardView'] !== undefined) {
-                    form['dashboardView'] = parameters['dashboardView'];
-                }
-
-                if (parameters['dashboardView'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: dashboardView'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters['url'] !== undefined) {
-                    form['url'] = parameters['url'];
-                }
-
-                if (parameters['url'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Dashboard_View_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} controller - 
-             * @param {string} dashboardView - 
-             * @param {boolean} enabled - 
-             * @param {string} url - URL of Dashboard
-             * 
-             */
-            xos.prototype.Controller_Dashboard_View_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllerdashboardviews/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['controller'] !== undefined) {
-                    form['controller'] = parameters['controller'];
-                }
-
-                if (parameters['dashboardView'] !== undefined) {
-                    form['dashboardView'] = parameters['dashboardView'];
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters['url'] !== undefined) {
-                    form['url'] = parameters['url'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Dashboard_View_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Controller_Dashboard_View_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllerdashboardviews/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Account_List_GET
-             * 
-             */
-            xos.prototype.Account_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/accounts/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Account_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} site - Site for this account
-             * 
-             */
-            xos.prototype.Account_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/accounts/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['site'] !== undefined) {
-                    form['site'] = parameters['site'];
-                }
-
-                if (parameters['site'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: site'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Account_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Account_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/accounts/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Account_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} site - Site for this account
-             * 
-             */
-            xos.prototype.Account_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/accounts/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['site'] !== undefined) {
-                    form['site'] = parameters['site'];
-                }
-
-                if (parameters['site'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: site'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Account_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} site - Site for this account
-             * 
-             */
-            xos.prototype.Account_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/accounts/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['site'] !== undefined) {
-                    form['site'] = parameters['site'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Account_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Account_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/accounts/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tenant_Root_List_GET
-             * 
-             */
-            xos.prototype.Tenant_Root_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tenantroots/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tenant_Root_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} kind - 
-             * @param {string} name - name
-             * @param {string} service_specific_attribute - 
-             * @param {string} service_specific_id - 
-             * 
-             */
-            xos.prototype.Tenant_Root_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tenantroots/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['kind'] !== undefined) {
-                    form['kind'] = parameters['kind'];
-                }
-
-                if (parameters['kind'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: kind'));
-                    return deferred.promise;
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['service_specific_attribute'] !== undefined) {
-                    form['service_specific_attribute'] = parameters['service_specific_attribute'];
-                }
-
-                if (parameters['service_specific_id'] !== undefined) {
-                    form['service_specific_id'] = parameters['service_specific_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tenant_Root_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Tenant_Root_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tenantroots/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tenant_Root_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} kind - 
-             * @param {string} name - name
-             * @param {string} service_specific_attribute - 
-             * @param {string} service_specific_id - 
-             * 
-             */
-            xos.prototype.Tenant_Root_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tenantroots/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['kind'] !== undefined) {
-                    form['kind'] = parameters['kind'];
-                }
-
-                if (parameters['kind'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: kind'));
-                    return deferred.promise;
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['service_specific_attribute'] !== undefined) {
-                    form['service_specific_attribute'] = parameters['service_specific_attribute'];
-                }
-
-                if (parameters['service_specific_id'] !== undefined) {
-                    form['service_specific_id'] = parameters['service_specific_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tenant_Root_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} kind - 
-             * @param {string} name - name
-             * @param {string} service_specific_attribute - 
-             * @param {string} service_specific_id - 
-             * 
-             */
-            xos.prototype.Tenant_Root_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tenantroots/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['kind'] !== undefined) {
-                    form['kind'] = parameters['kind'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['service_specific_attribute'] !== undefined) {
-                    form['service_specific_attribute'] = parameters['service_specific_attribute'];
-                }
-
-                if (parameters['service_specific_id'] !== undefined) {
-                    form['service_specific_id'] = parameters['service_specific_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tenant_Root_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Tenant_Root_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tenantroots/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Role_List_GET
-             * 
-             */
-            xos.prototype.Controller_Role_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllerroles/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Role_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-
-             * 
-             */
-            xos.prototype.Controller_Role_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllerroles/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                form['role'] = 'admin';
-
-                if (parameters['role'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: role'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Role_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Controller_Role_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllerroles/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Role_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-
-             * 
-             */
-            xos.prototype.Controller_Role_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllerroles/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                form['role'] = 'admin';
-
-                if (parameters['role'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: role'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Role_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-
-             * 
-             */
-            xos.prototype.Controller_Role_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllerroles/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                form['role'] = 'admin';
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Role_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Controller_Role_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllerroles/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Network_Parameter_Type_List_GET
-             * 
-             */
-            xos.prototype.Network_Parameter_Type_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/networkparametertypes/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Network_Parameter_Type_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - The name of this parameter
-             * @param {string} description - 
-             * 
-             */
-            xos.prototype.Network_Parameter_Type_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/networkparametertypes/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['description'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: description'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Network_Parameter_Type_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Network_Parameter_Type_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/networkparametertypes/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Network_Parameter_Type_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - The name of this parameter
-             * @param {string} description - 
-             * 
-             */
-            xos.prototype.Network_Parameter_Type_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/networkparametertypes/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['description'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: description'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Network_Parameter_Type_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - The name of this parameter
-             * @param {string} description - 
-             * 
-             */
-            xos.prototype.Network_Parameter_Type_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/networkparametertypes/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Network_Parameter_Type_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Network_Parameter_Type_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/networkparametertypes/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Site_Credential_List_GET
-             * 
-             */
-            xos.prototype.Site_Credential_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/sitecredentials/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Site_Credential_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} site - The User this credential is associated with
-             * @param {string} name - The credential type, e.g. ec2
-             * @param {string} key_id - The backend id of this credential
-             * @param {string} enc_value - The key value of this credential
-             * 
-             */
-            xos.prototype.Site_Credential_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/sitecredentials/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['site'] !== undefined) {
-                    form['site'] = parameters['site'];
-                }
-
-                if (parameters['site'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: site'));
-                    return deferred.promise;
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['key_id'] !== undefined) {
-                    form['key_id'] = parameters['key_id'];
-                }
-
-                if (parameters['key_id'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: key_id'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enc_value'] !== undefined) {
-                    form['enc_value'] = parameters['enc_value'];
-                }
-
-                if (parameters['enc_value'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: enc_value'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Site_Credential_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Site_Credential_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/sitecredentials/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Site_Credential_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} site - The User this credential is associated with
-             * @param {string} name - The credential type, e.g. ec2
-             * @param {string} key_id - The backend id of this credential
-             * @param {string} enc_value - The key value of this credential
-             * 
-             */
-            xos.prototype.Site_Credential_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/sitecredentials/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['site'] !== undefined) {
-                    form['site'] = parameters['site'];
-                }
-
-                if (parameters['site'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: site'));
-                    return deferred.promise;
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['key_id'] !== undefined) {
-                    form['key_id'] = parameters['key_id'];
-                }
-
-                if (parameters['key_id'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: key_id'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enc_value'] !== undefined) {
-                    form['enc_value'] = parameters['enc_value'];
-                }
-
-                if (parameters['enc_value'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: enc_value'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Site_Credential_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} site - The User this credential is associated with
-             * @param {string} name - The credential type, e.g. ec2
-             * @param {string} key_id - The backend id of this credential
-             * @param {string} enc_value - The key value of this credential
-             * 
-             */
-            xos.prototype.Site_Credential_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/sitecredentials/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['site'] !== undefined) {
-                    form['site'] = parameters['site'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['key_id'] !== undefined) {
-                    form['key_id'] = parameters['key_id'];
-                }
-
-                if (parameters['enc_value'] !== undefined) {
-                    form['enc_value'] = parameters['enc_value'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Site_Credential_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Site_Credential_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/sitecredentials/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Deployment_Privilege_List_GET
-             * 
-             */
-            xos.prototype.Deployment_Privilege_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/deploymentprivileges/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Deployment_Privilege_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} user - 
-             * @param {string} deployment - 
-             * @param {string} role - 
-             * 
-             */
-            xos.prototype.Deployment_Privilege_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/deploymentprivileges/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['user'] !== undefined) {
-                    form['user'] = parameters['user'];
-                }
-
-                if (parameters['user'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: user'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deployment'] !== undefined) {
-                    form['deployment'] = parameters['deployment'];
-                }
-
-                if (parameters['deployment'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: deployment'));
-                    return deferred.promise;
-                }
-
-                if (parameters['role'] !== undefined) {
-                    form['role'] = parameters['role'];
-                }
-
-                if (parameters['role'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: role'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Deployment_Privilege_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Deployment_Privilege_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/deploymentprivileges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Deployment_Privilege_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} user - 
-             * @param {string} deployment - 
-             * @param {string} role - 
-             * 
-             */
-            xos.prototype.Deployment_Privilege_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/deploymentprivileges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['user'] !== undefined) {
-                    form['user'] = parameters['user'];
-                }
-
-                if (parameters['user'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: user'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deployment'] !== undefined) {
-                    form['deployment'] = parameters['deployment'];
-                }
-
-                if (parameters['deployment'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: deployment'));
-                    return deferred.promise;
-                }
-
-                if (parameters['role'] !== undefined) {
-                    form['role'] = parameters['role'];
-                }
-
-                if (parameters['role'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: role'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Deployment_Privilege_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} user - 
-             * @param {string} deployment - 
-             * @param {string} role - 
-             * 
-             */
-            xos.prototype.Deployment_Privilege_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/deploymentprivileges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['user'] !== undefined) {
-                    form['user'] = parameters['user'];
-                }
-
-                if (parameters['deployment'] !== undefined) {
-                    form['deployment'] = parameters['deployment'];
-                }
-
-                if (parameters['role'] !== undefined) {
-                    form['role'] = parameters['role'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Deployment_Privilege_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Deployment_Privilege_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/deploymentprivileges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Slice_Privilege_List_GET
-             * 
-             */
-            xos.prototype.Controller_Slice_Privilege_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllersliceprivileges/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Slice_Privilege_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} controller - 
-             * @param {string} slice_privilege - 
-             * @param {string} role_id - Keystone id
-             * 
-             */
-            xos.prototype.Controller_Slice_Privilege_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllersliceprivileges/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['controller'] !== undefined) {
-                    form['controller'] = parameters['controller'];
-                }
-
-                if (parameters['controller'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: controller'));
-                    return deferred.promise;
-                }
-
-                if (parameters['slice_privilege'] !== undefined) {
-                    form['slice_privilege'] = parameters['slice_privilege'];
-                }
-
-                if (parameters['slice_privilege'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: slice_privilege'));
-                    return deferred.promise;
-                }
-
-                if (parameters['role_id'] !== undefined) {
-                    form['role_id'] = parameters['role_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Slice_Privilege_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Controller_Slice_Privilege_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllersliceprivileges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Slice_Privilege_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} controller - 
-             * @param {string} slice_privilege - 
-             * @param {string} role_id - Keystone id
-             * 
-             */
-            xos.prototype.Controller_Slice_Privilege_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllersliceprivileges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['controller'] !== undefined) {
-                    form['controller'] = parameters['controller'];
-                }
-
-                if (parameters['controller'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: controller'));
-                    return deferred.promise;
-                }
-
-                if (parameters['slice_privilege'] !== undefined) {
-                    form['slice_privilege'] = parameters['slice_privilege'];
-                }
-
-                if (parameters['slice_privilege'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: slice_privilege'));
-                    return deferred.promise;
-                }
-
-                if (parameters['role_id'] !== undefined) {
-                    form['role_id'] = parameters['role_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Slice_Privilege_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} controller - 
-             * @param {string} slice_privilege - 
-             * @param {string} role_id - Keystone id
-             * 
-             */
-            xos.prototype.Controller_Slice_Privilege_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllersliceprivileges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['controller'] !== undefined) {
-                    form['controller'] = parameters['controller'];
-                }
-
-                if (parameters['slice_privilege'] !== undefined) {
-                    form['slice_privilege'] = parameters['slice_privilege'];
-                }
-
-                if (parameters['role_id'] !== undefined) {
-                    form['role_id'] = parameters['role_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Controller_Slice_Privilege_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Controller_Slice_Privilege_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/controllersliceprivileges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Site_Deployment_List_GET
-             * 
-             */
-            xos.prototype.Site_Deployment_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/sitedeployments/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Site_Deployment_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} site - 
-             * @param {string} deployment - 
-             * @param {string} controller - 
-             * @param {string} availability_zone - OpenStack availability zone
-             * 
-             */
-            xos.prototype.Site_Deployment_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/sitedeployments/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['site'] !== undefined) {
-                    form['site'] = parameters['site'];
-                }
-
-                if (parameters['site'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: site'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deployment'] !== undefined) {
-                    form['deployment'] = parameters['deployment'];
-                }
-
-                if (parameters['deployment'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: deployment'));
-                    return deferred.promise;
-                }
-
-                if (parameters['controller'] !== undefined) {
-                    form['controller'] = parameters['controller'];
-                }
-
-                if (parameters['availability_zone'] !== undefined) {
-                    form['availability_zone'] = parameters['availability_zone'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Site_Deployment_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Site_Deployment_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/sitedeployments/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Site_Deployment_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} site - 
-             * @param {string} deployment - 
-             * @param {string} controller - 
-             * @param {string} availability_zone - OpenStack availability zone
-             * 
-             */
-            xos.prototype.Site_Deployment_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/sitedeployments/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['site'] !== undefined) {
-                    form['site'] = parameters['site'];
-                }
-
-                if (parameters['site'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: site'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deployment'] !== undefined) {
-                    form['deployment'] = parameters['deployment'];
-                }
-
-                if (parameters['deployment'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: deployment'));
-                    return deferred.promise;
-                }
-
-                if (parameters['controller'] !== undefined) {
-                    form['controller'] = parameters['controller'];
-                }
-
-                if (parameters['availability_zone'] !== undefined) {
-                    form['availability_zone'] = parameters['availability_zone'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Site_Deployment_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} site - 
-             * @param {string} deployment - 
-             * @param {string} controller - 
-             * @param {string} availability_zone - OpenStack availability zone
-             * 
-             */
-            xos.prototype.Site_Deployment_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/sitedeployments/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['site'] !== undefined) {
-                    form['site'] = parameters['site'];
-                }
-
-                if (parameters['deployment'] !== undefined) {
-                    form['deployment'] = parameters['deployment'];
-                }
-
-                if (parameters['controller'] !== undefined) {
-                    form['controller'] = parameters['controller'];
-                }
-
-                if (parameters['availability_zone'] !== undefined) {
-                    form['availability_zone'] = parameters['availability_zone'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Site_Deployment_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Site_Deployment_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/sitedeployments/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tenant_With_Container_List_GET
-             * 
-             */
-            xos.prototype.Tenant_With_Container_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tenantwithcontainers/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tenant_With_Container_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} kind - 
-             * @param {string} provider_service - 
-             * @param {string} subscriber_service - 
-             * @param {string} subscriber_tenant - 
-             * @param {string} subscriber_user - 
-             * @param {string} subscriber_root - 
-             * @param {string} service_specific_id - 
-             * @param {string} service_specific_attribute - 
-             * @param {choice} connect_method - 
-             * 
-             */
-            xos.prototype.Tenant_With_Container_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tenantwithcontainers/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['kind'] !== undefined) {
-                    form['kind'] = parameters['kind'];
-                }
-
-                if (parameters['kind'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: kind'));
-                    return deferred.promise;
-                }
-
-                if (parameters['provider_service'] !== undefined) {
-                    form['provider_service'] = parameters['provider_service'];
-                }
-
-                if (parameters['provider_service'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: provider_service'));
-                    return deferred.promise;
-                }
-
-                if (parameters['subscriber_service'] !== undefined) {
-                    form['subscriber_service'] = parameters['subscriber_service'];
-                }
-
-                if (parameters['subscriber_tenant'] !== undefined) {
-                    form['subscriber_tenant'] = parameters['subscriber_tenant'];
-                }
-
-                if (parameters['subscriber_user'] !== undefined) {
-                    form['subscriber_user'] = parameters['subscriber_user'];
-                }
-
-                if (parameters['subscriber_root'] !== undefined) {
-                    form['subscriber_root'] = parameters['subscriber_root'];
-                }
-
-                if (parameters['service_specific_id'] !== undefined) {
-                    form['service_specific_id'] = parameters['service_specific_id'];
-                }
-
-                if (parameters['service_specific_attribute'] !== undefined) {
-                    form['service_specific_attribute'] = parameters['service_specific_attribute'];
-                }
-
-                if (parameters['connect_method'] !== undefined) {
-                    form['connect_method'] = parameters['connect_method'];
-                }
-
-                if (parameters['connect_method'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: connect_method'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tenant_With_Container_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Tenant_With_Container_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tenantwithcontainers/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tenant_With_Container_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} kind - 
-             * @param {string} provider_service - 
-             * @param {string} subscriber_service - 
-             * @param {string} subscriber_tenant - 
-             * @param {string} subscriber_user - 
-             * @param {string} subscriber_root - 
-             * @param {string} service_specific_id - 
-             * @param {string} service_specific_attribute - 
-             * @param {choice} connect_method - 
-             * 
-             */
-            xos.prototype.Tenant_With_Container_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tenantwithcontainers/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['kind'] !== undefined) {
-                    form['kind'] = parameters['kind'];
-                }
-
-                if (parameters['kind'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: kind'));
-                    return deferred.promise;
-                }
-
-                if (parameters['provider_service'] !== undefined) {
-                    form['provider_service'] = parameters['provider_service'];
-                }
-
-                if (parameters['provider_service'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: provider_service'));
-                    return deferred.promise;
-                }
-
-                if (parameters['subscriber_service'] !== undefined) {
-                    form['subscriber_service'] = parameters['subscriber_service'];
-                }
-
-                if (parameters['subscriber_tenant'] !== undefined) {
-                    form['subscriber_tenant'] = parameters['subscriber_tenant'];
-                }
-
-                if (parameters['subscriber_user'] !== undefined) {
-                    form['subscriber_user'] = parameters['subscriber_user'];
-                }
-
-                if (parameters['subscriber_root'] !== undefined) {
-                    form['subscriber_root'] = parameters['subscriber_root'];
-                }
-
-                if (parameters['service_specific_id'] !== undefined) {
-                    form['service_specific_id'] = parameters['service_specific_id'];
-                }
-
-                if (parameters['service_specific_attribute'] !== undefined) {
-                    form['service_specific_attribute'] = parameters['service_specific_attribute'];
-                }
-
-                if (parameters['connect_method'] !== undefined) {
-                    form['connect_method'] = parameters['connect_method'];
-                }
-
-                if (parameters['connect_method'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: connect_method'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tenant_With_Container_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} kind - 
-             * @param {string} provider_service - 
-             * @param {string} subscriber_service - 
-             * @param {string} subscriber_tenant - 
-             * @param {string} subscriber_user - 
-             * @param {string} subscriber_root - 
-             * @param {string} service_specific_id - 
-             * @param {string} service_specific_attribute - 
-             * @param {choice} connect_method - 
-             * 
-             */
-            xos.prototype.Tenant_With_Container_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tenantwithcontainers/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['kind'] !== undefined) {
-                    form['kind'] = parameters['kind'];
-                }
-
-                if (parameters['provider_service'] !== undefined) {
-                    form['provider_service'] = parameters['provider_service'];
-                }
-
-                if (parameters['subscriber_service'] !== undefined) {
-                    form['subscriber_service'] = parameters['subscriber_service'];
-                }
-
-                if (parameters['subscriber_tenant'] !== undefined) {
-                    form['subscriber_tenant'] = parameters['subscriber_tenant'];
-                }
-
-                if (parameters['subscriber_user'] !== undefined) {
-                    form['subscriber_user'] = parameters['subscriber_user'];
-                }
-
-                if (parameters['subscriber_root'] !== undefined) {
-                    form['subscriber_root'] = parameters['subscriber_root'];
-                }
-
-                if (parameters['service_specific_id'] !== undefined) {
-                    form['service_specific_id'] = parameters['service_specific_id'];
-                }
-
-                if (parameters['service_specific_attribute'] !== undefined) {
-                    form['service_specific_attribute'] = parameters['service_specific_attribute'];
-                }
-
-                if (parameters['connect_method'] !== undefined) {
-                    form['connect_method'] = parameters['connect_method'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tenant_With_Container_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Tenant_With_Container_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tenantwithcontainers/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Deployment_Role_List_GET
-             * 
-             */
-            xos.prototype.Deployment_Role_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/deploymentroles/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Deployment_Role_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-
-             * 
-             */
-            xos.prototype.Deployment_Role_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/deploymentroles/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                form['role'] = 'admin';
-
-                if (parameters['role'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: role'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Deployment_Role_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Deployment_Role_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/deploymentroles/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Deployment_Role_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-
-             * 
-             */
-            xos.prototype.Deployment_Role_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/deploymentroles/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                form['role'] = 'admin';
-
-                if (parameters['role'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: role'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Deployment_Role_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-
-             * 
-             */
-            xos.prototype.Deployment_Role_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/deploymentroles/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                form['role'] = 'admin';
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Deployment_Role_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Deployment_Role_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/deploymentroles/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#User_Credential_List_GET
-             * 
-             */
-            xos.prototype.User_Credential_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/usercredentials/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#User_Credential_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} user - The User this credential is associated with
-             * @param {string} name - The credential type, e.g. ec2
-             * @param {string} key_id - The backend id of this credential
-             * @param {string} enc_value - The key value of this credential
-             * 
-             */
-            xos.prototype.User_Credential_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/usercredentials/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['user'] !== undefined) {
-                    form['user'] = parameters['user'];
-                }
-
-                if (parameters['user'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: user'));
-                    return deferred.promise;
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['key_id'] !== undefined) {
-                    form['key_id'] = parameters['key_id'];
-                }
-
-                if (parameters['key_id'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: key_id'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enc_value'] !== undefined) {
-                    form['enc_value'] = parameters['enc_value'];
-                }
-
-                if (parameters['enc_value'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: enc_value'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#User_Credential_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.User_Credential_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/usercredentials/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#User_Credential_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} user - The User this credential is associated with
-             * @param {string} name - The credential type, e.g. ec2
-             * @param {string} key_id - The backend id of this credential
-             * @param {string} enc_value - The key value of this credential
-             * 
-             */
-            xos.prototype.User_Credential_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/usercredentials/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['user'] !== undefined) {
-                    form['user'] = parameters['user'];
-                }
-
-                if (parameters['user'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: user'));
-                    return deferred.promise;
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['key_id'] !== undefined) {
-                    form['key_id'] = parameters['key_id'];
-                }
-
-                if (parameters['key_id'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: key_id'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enc_value'] !== undefined) {
-                    form['enc_value'] = parameters['enc_value'];
-                }
-
-                if (parameters['enc_value'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: enc_value'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#User_Credential_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} user - The User this credential is associated with
-             * @param {string} name - The credential type, e.g. ec2
-             * @param {string} key_id - The backend id of this credential
-             * @param {string} enc_value - The key value of this credential
-             * 
-             */
-            xos.prototype.User_Credential_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/usercredentials/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['user'] !== undefined) {
-                    form['user'] = parameters['user'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['key_id'] !== undefined) {
-                    form['key_id'] = parameters['key_id'];
-                }
-
-                if (parameters['enc_value'] !== undefined) {
-                    form['enc_value'] = parameters['enc_value'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#User_Credential_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.User_Credential_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/usercredentials/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tenant_Root_Privilege_List_GET
-             * 
-             */
-            xos.prototype.Tenant_Root_Privilege_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tenantrootprivileges/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tenant_Root_Privilege_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} user - 
-             * @param {string} tenant_root - 
-             * @param {string} role - 
-             * 
-             */
-            xos.prototype.Tenant_Root_Privilege_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tenantrootprivileges/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['user'] !== undefined) {
-                    form['user'] = parameters['user'];
-                }
-
-                if (parameters['user'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: user'));
-                    return deferred.promise;
-                }
-
-                if (parameters['tenant_root'] !== undefined) {
-                    form['tenant_root'] = parameters['tenant_root'];
-                }
-
-                if (parameters['tenant_root'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: tenant_root'));
-                    return deferred.promise;
-                }
-
-                if (parameters['role'] !== undefined) {
-                    form['role'] = parameters['role'];
-                }
-
-                if (parameters['role'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: role'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tenant_Root_Privilege_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Tenant_Root_Privilege_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tenantrootprivileges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tenant_Root_Privilege_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} user - 
-             * @param {string} tenant_root - 
-             * @param {string} role - 
-             * 
-             */
-            xos.prototype.Tenant_Root_Privilege_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tenantrootprivileges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['user'] !== undefined) {
-                    form['user'] = parameters['user'];
-                }
-
-                if (parameters['user'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: user'));
-                    return deferred.promise;
-                }
-
-                if (parameters['tenant_root'] !== undefined) {
-                    form['tenant_root'] = parameters['tenant_root'];
-                }
-
-                if (parameters['tenant_root'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: tenant_root'));
-                    return deferred.promise;
-                }
-
-                if (parameters['role'] !== undefined) {
-                    form['role'] = parameters['role'];
-                }
-
-                if (parameters['role'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: role'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tenant_Root_Privilege_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} user - 
-             * @param {string} tenant_root - 
-             * @param {string} role - 
-             * 
-             */
-            xos.prototype.Tenant_Root_Privilege_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tenantrootprivileges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['user'] !== undefined) {
-                    form['user'] = parameters['user'];
-                }
-
-                if (parameters['tenant_root'] !== undefined) {
-                    form['tenant_root'] = parameters['tenant_root'];
-                }
-
-                if (parameters['role'] !== undefined) {
-                    form['role'] = parameters['role'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Tenant_Root_Privilege_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Tenant_Root_Privilege_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/tenantrootprivileges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Slice_Tag_List_GET
-             * 
-             */
-            xos.prototype.Slice_Tag_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/slicetags/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Slice_Tag_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} slice - 
-             * @param {choice} name - The name of this tag
-             * @param {string} value - The value of this tag
-             * 
-             */
-            xos.prototype.Slice_Tag_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/slicetags/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['slice'] !== undefined) {
-                    form['slice'] = parameters['slice'];
-                }
-
-                if (parameters['slice'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: slice'));
-                    return deferred.promise;
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['value'] !== undefined) {
-                    form['value'] = parameters['value'];
-                }
-
-                if (parameters['value'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: value'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Slice_Tag_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Slice_Tag_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/slicetags/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Slice_Tag_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} slice - 
-             * @param {choice} name - The name of this tag
-             * @param {string} value - The value of this tag
-             * 
-             */
-            xos.prototype.Slice_Tag_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/slicetags/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['slice'] !== undefined) {
-                    form['slice'] = parameters['slice'];
-                }
-
-                if (parameters['slice'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: slice'));
-                    return deferred.promise;
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['value'] !== undefined) {
-                    form['value'] = parameters['value'];
-                }
-
-                if (parameters['value'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: value'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Slice_Tag_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} slice - 
-             * @param {choice} name - The name of this tag
-             * @param {string} value - The value of this tag
-             * 
-             */
-            xos.prototype.Slice_Tag_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/slicetags/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['slice'] !== undefined) {
-                    form['slice'] = parameters['slice'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['value'] !== undefined) {
-                    form['value'] = parameters['value'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Slice_Tag_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Slice_Tag_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/slicetags/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Coarse_Tenant_List_GET
-             * 
-             */
-            xos.prototype.Coarse_Tenant_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/coarsetenants/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Coarse_Tenant_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} kind - 
-             * @param {string} provider_service - 
-             * @param {string} subscriber_service - 
-             * @param {string} subscriber_tenant - 
-             * @param {string} subscriber_user - 
-             * @param {string} subscriber_root - 
-             * @param {string} service_specific_id - 
-             * @param {string} service_specific_attribute - 
-             * @param {choice} connect_method - 
-             * 
-             */
-            xos.prototype.Coarse_Tenant_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/coarsetenants/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['kind'] !== undefined) {
-                    form['kind'] = parameters['kind'];
-                }
-
-                if (parameters['kind'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: kind'));
-                    return deferred.promise;
-                }
-
-                if (parameters['provider_service'] !== undefined) {
-                    form['provider_service'] = parameters['provider_service'];
-                }
-
-                if (parameters['provider_service'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: provider_service'));
-                    return deferred.promise;
-                }
-
-                if (parameters['subscriber_service'] !== undefined) {
-                    form['subscriber_service'] = parameters['subscriber_service'];
-                }
-
-                if (parameters['subscriber_tenant'] !== undefined) {
-                    form['subscriber_tenant'] = parameters['subscriber_tenant'];
-                }
-
-                if (parameters['subscriber_user'] !== undefined) {
-                    form['subscriber_user'] = parameters['subscriber_user'];
-                }
-
-                if (parameters['subscriber_root'] !== undefined) {
-                    form['subscriber_root'] = parameters['subscriber_root'];
-                }
-
-                if (parameters['service_specific_id'] !== undefined) {
-                    form['service_specific_id'] = parameters['service_specific_id'];
-                }
-
-                if (parameters['service_specific_attribute'] !== undefined) {
-                    form['service_specific_attribute'] = parameters['service_specific_attribute'];
-                }
-
-                if (parameters['connect_method'] !== undefined) {
-                    form['connect_method'] = parameters['connect_method'];
-                }
-
-                if (parameters['connect_method'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: connect_method'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Coarse_Tenant_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Coarse_Tenant_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/coarsetenants/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Coarse_Tenant_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} kind - 
-             * @param {string} provider_service - 
-             * @param {string} subscriber_service - 
-             * @param {string} subscriber_tenant - 
-             * @param {string} subscriber_user - 
-             * @param {string} subscriber_root - 
-             * @param {string} service_specific_id - 
-             * @param {string} service_specific_attribute - 
-             * @param {choice} connect_method - 
-             * 
-             */
-            xos.prototype.Coarse_Tenant_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/coarsetenants/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['kind'] !== undefined) {
-                    form['kind'] = parameters['kind'];
-                }
-
-                if (parameters['kind'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: kind'));
-                    return deferred.promise;
-                }
-
-                if (parameters['provider_service'] !== undefined) {
-                    form['provider_service'] = parameters['provider_service'];
-                }
-
-                if (parameters['provider_service'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: provider_service'));
-                    return deferred.promise;
-                }
-
-                if (parameters['subscriber_service'] !== undefined) {
-                    form['subscriber_service'] = parameters['subscriber_service'];
-                }
-
-                if (parameters['subscriber_tenant'] !== undefined) {
-                    form['subscriber_tenant'] = parameters['subscriber_tenant'];
-                }
-
-                if (parameters['subscriber_user'] !== undefined) {
-                    form['subscriber_user'] = parameters['subscriber_user'];
-                }
-
-                if (parameters['subscriber_root'] !== undefined) {
-                    form['subscriber_root'] = parameters['subscriber_root'];
-                }
-
-                if (parameters['service_specific_id'] !== undefined) {
-                    form['service_specific_id'] = parameters['service_specific_id'];
-                }
-
-                if (parameters['service_specific_attribute'] !== undefined) {
-                    form['service_specific_attribute'] = parameters['service_specific_attribute'];
-                }
-
-                if (parameters['connect_method'] !== undefined) {
-                    form['connect_method'] = parameters['connect_method'];
-                }
-
-                if (parameters['connect_method'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: connect_method'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Coarse_Tenant_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} kind - 
-             * @param {string} provider_service - 
-             * @param {string} subscriber_service - 
-             * @param {string} subscriber_tenant - 
-             * @param {string} subscriber_user - 
-             * @param {string} subscriber_root - 
-             * @param {string} service_specific_id - 
-             * @param {string} service_specific_attribute - 
-             * @param {choice} connect_method - 
-             * 
-             */
-            xos.prototype.Coarse_Tenant_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/coarsetenants/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['kind'] !== undefined) {
-                    form['kind'] = parameters['kind'];
-                }
-
-                if (parameters['provider_service'] !== undefined) {
-                    form['provider_service'] = parameters['provider_service'];
-                }
-
-                if (parameters['subscriber_service'] !== undefined) {
-                    form['subscriber_service'] = parameters['subscriber_service'];
-                }
-
-                if (parameters['subscriber_tenant'] !== undefined) {
-                    form['subscriber_tenant'] = parameters['subscriber_tenant'];
-                }
-
-                if (parameters['subscriber_user'] !== undefined) {
-                    form['subscriber_user'] = parameters['subscriber_user'];
-                }
-
-                if (parameters['subscriber_root'] !== undefined) {
-                    form['subscriber_root'] = parameters['subscriber_root'];
-                }
-
-                if (parameters['service_specific_id'] !== undefined) {
-                    form['service_specific_id'] = parameters['service_specific_id'];
-                }
-
-                if (parameters['service_specific_attribute'] !== undefined) {
-                    form['service_specific_attribute'] = parameters['service_specific_attribute'];
-                }
-
-                if (parameters['connect_method'] !== undefined) {
-                    form['connect_method'] = parameters['connect_method'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Coarse_Tenant_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Coarse_Tenant_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/coarsetenants/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Router_List_GET
-             * 
-             */
-            xos.prototype.Router_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/routers/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Router_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - 
-             * @param {string} owner - 
-             * 
-             */
-            xos.prototype.Router_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/routers/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['owner'] !== undefined) {
-                    form['owner'] = parameters['owner'];
-                }
-
-                if (parameters['owner'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: owner'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Router_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Router_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/routers/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Router_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - 
-             * @param {string} owner - 
-             * 
-             */
-            xos.prototype.Router_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/routers/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['owner'] !== undefined) {
-                    form['owner'] = parameters['owner'];
-                }
-
-                if (parameters['owner'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: owner'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Router_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} name - 
-             * @param {string} owner - 
-             * 
-             */
-            xos.prototype.Router_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/routers/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['owner'] !== undefined) {
-                    form['owner'] = parameters['owner'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Router_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Router_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/routers/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Service_Resource_List_GET
-             * 
-             */
-            xos.prototype.Service_Resource_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/serviceresources/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Service_Resource_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} serviceClass - 
-             * @param {string} name - 
-             * @param {integer} maxUnitsDeployment - 
-             * @param {integer} maxUnitsNode - 
-             * @param {integer} maxDuration - 
-             * @param {integer} bucketInRate - 
-             * @param {integer} bucketMaxSize - 
-             * @param {integer} cost - 
-             * @param {boolean} calendarReservable - 
-             * 
-             */
-            xos.prototype.Service_Resource_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/serviceresources/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['serviceClass'] !== undefined) {
-                    form['serviceClass'] = parameters['serviceClass'];
-                }
-
-                if (parameters['serviceClass'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: serviceClass'));
-                    return deferred.promise;
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['maxUnitsDeployment'] !== undefined) {
-                    form['maxUnitsDeployment'] = parameters['maxUnitsDeployment'];
-                }
-
-                if (parameters['maxUnitsDeployment'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: maxUnitsDeployment'));
-                    return deferred.promise;
-                }
-
-                if (parameters['maxUnitsNode'] !== undefined) {
-                    form['maxUnitsNode'] = parameters['maxUnitsNode'];
-                }
-
-                if (parameters['maxUnitsNode'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: maxUnitsNode'));
-                    return deferred.promise;
-                }
-
-                if (parameters['maxDuration'] !== undefined) {
-                    form['maxDuration'] = parameters['maxDuration'];
-                }
-
-                if (parameters['maxDuration'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: maxDuration'));
-                    return deferred.promise;
-                }
-
-                if (parameters['bucketInRate'] !== undefined) {
-                    form['bucketInRate'] = parameters['bucketInRate'];
-                }
-
-                if (parameters['bucketInRate'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: bucketInRate'));
-                    return deferred.promise;
-                }
-
-                if (parameters['bucketMaxSize'] !== undefined) {
-                    form['bucketMaxSize'] = parameters['bucketMaxSize'];
-                }
-
-                if (parameters['bucketMaxSize'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: bucketMaxSize'));
-                    return deferred.promise;
-                }
-
-                if (parameters['cost'] !== undefined) {
-                    form['cost'] = parameters['cost'];
-                }
-
-                if (parameters['cost'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: cost'));
-                    return deferred.promise;
-                }
-
-                if (parameters['calendarReservable'] !== undefined) {
-                    form['calendarReservable'] = parameters['calendarReservable'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Service_Resource_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Service_Resource_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/serviceresources/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Service_Resource_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} serviceClass - 
-             * @param {string} name - 
-             * @param {integer} maxUnitsDeployment - 
-             * @param {integer} maxUnitsNode - 
-             * @param {integer} maxDuration - 
-             * @param {integer} bucketInRate - 
-             * @param {integer} bucketMaxSize - 
-             * @param {integer} cost - 
-             * @param {boolean} calendarReservable - 
-             * 
-             */
-            xos.prototype.Service_Resource_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/serviceresources/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['serviceClass'] !== undefined) {
-                    form['serviceClass'] = parameters['serviceClass'];
-                }
-
-                if (parameters['serviceClass'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: serviceClass'));
-                    return deferred.promise;
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['maxUnitsDeployment'] !== undefined) {
-                    form['maxUnitsDeployment'] = parameters['maxUnitsDeployment'];
-                }
-
-                if (parameters['maxUnitsDeployment'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: maxUnitsDeployment'));
-                    return deferred.promise;
-                }
-
-                if (parameters['maxUnitsNode'] !== undefined) {
-                    form['maxUnitsNode'] = parameters['maxUnitsNode'];
-                }
-
-                if (parameters['maxUnitsNode'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: maxUnitsNode'));
-                    return deferred.promise;
-                }
-
-                if (parameters['maxDuration'] !== undefined) {
-                    form['maxDuration'] = parameters['maxDuration'];
-                }
-
-                if (parameters['maxDuration'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: maxDuration'));
-                    return deferred.promise;
-                }
-
-                if (parameters['bucketInRate'] !== undefined) {
-                    form['bucketInRate'] = parameters['bucketInRate'];
-                }
-
-                if (parameters['bucketInRate'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: bucketInRate'));
-                    return deferred.promise;
-                }
-
-                if (parameters['bucketMaxSize'] !== undefined) {
-                    form['bucketMaxSize'] = parameters['bucketMaxSize'];
-                }
-
-                if (parameters['bucketMaxSize'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: bucketMaxSize'));
-                    return deferred.promise;
-                }
-
-                if (parameters['cost'] !== undefined) {
-                    form['cost'] = parameters['cost'];
-                }
-
-                if (parameters['cost'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: cost'));
-                    return deferred.promise;
-                }
-
-                if (parameters['calendarReservable'] !== undefined) {
-                    form['calendarReservable'] = parameters['calendarReservable'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Service_Resource_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} serviceClass - 
-             * @param {string} name - 
-             * @param {integer} maxUnitsDeployment - 
-             * @param {integer} maxUnitsNode - 
-             * @param {integer} maxDuration - 
-             * @param {integer} bucketInRate - 
-             * @param {integer} bucketMaxSize - 
-             * @param {integer} cost - 
-             * @param {boolean} calendarReservable - 
-             * 
-             */
-            xos.prototype.Service_Resource_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/serviceresources/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['serviceClass'] !== undefined) {
-                    form['serviceClass'] = parameters['serviceClass'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['maxUnitsDeployment'] !== undefined) {
-                    form['maxUnitsDeployment'] = parameters['maxUnitsDeployment'];
-                }
-
-                if (parameters['maxUnitsNode'] !== undefined) {
-                    form['maxUnitsNode'] = parameters['maxUnitsNode'];
-                }
-
-                if (parameters['maxDuration'] !== undefined) {
-                    form['maxDuration'] = parameters['maxDuration'];
-                }
-
-                if (parameters['bucketInRate'] !== undefined) {
-                    form['bucketInRate'] = parameters['bucketInRate'];
-                }
-
-                if (parameters['bucketMaxSize'] !== undefined) {
-                    form['bucketMaxSize'] = parameters['bucketMaxSize'];
-                }
-
-                if (parameters['cost'] !== undefined) {
-                    form['cost'] = parameters['cost'];
-                }
-
-                if (parameters['calendarReservable'] !== undefined) {
-                    form['calendarReservable'] = parameters['calendarReservable'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Service_Resource_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Service_Resource_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/serviceresources/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Service_Privilege_List_GET
-             * 
-             */
-            xos.prototype.Service_Privilege_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/serviceprivileges/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Service_Privilege_List_POST
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} user - 
-             * @param {string} service - 
-             * @param {string} role - 
-             * 
-             */
-            xos.prototype.Service_Privilege_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/serviceprivileges/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['user'] !== undefined) {
-                    form['user'] = parameters['user'];
-                }
-
-                if (parameters['user'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: user'));
-                    return deferred.promise;
-                }
-
-                if (parameters['service'] !== undefined) {
-                    form['service'] = parameters['service'];
-                }
-
-                if (parameters['service'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: service'));
-                    return deferred.promise;
-                }
-
-                if (parameters['role'] !== undefined) {
-                    form['role'] = parameters['role'];
-                }
-
-                if (parameters['role'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: role'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Service_Privilege_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Service_Privilege_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/serviceprivileges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Service_Privilege_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} user - 
-             * @param {string} service - 
-             * @param {string} role - 
-             * 
-             */
-            xos.prototype.Service_Privilege_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/serviceprivileges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['backend_status'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: backend_status'));
-                    return deferred.promise;
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['user'] !== undefined) {
-                    form['user'] = parameters['user'];
-                }
-
-                if (parameters['user'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: user'));
-                    return deferred.promise;
-                }
-
-                if (parameters['service'] !== undefined) {
-                    form['service'] = parameters['service'];
-                }
-
-                if (parameters['service'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: service'));
-                    return deferred.promise;
-                }
-
-                if (parameters['role'] !== undefined) {
-                    form['role'] = parameters['role'];
-                }
-
-                if (parameters['role'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: role'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Service_Privilege_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} policed - 
-             * @param {string} backend_register - 
-             * @param {string} backend_status - 
-             * @param {boolean} deleted - 
-             * @param {boolean} write_protect - 
-             * @param {boolean} lazy_blocked - 
-             * @param {boolean} no_sync - 
-             * @param {string} user - 
-             * @param {string} service - 
-             * @param {string} role - 
-             * 
-             */
-            xos.prototype.Service_Privilege_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/serviceprivileges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['policed'] !== undefined) {
-                    form['policed'] = parameters['policed'];
-                }
-
-                if (parameters['backend_register'] !== undefined) {
-                    form['backend_register'] = parameters['backend_register'];
-                }
-
-                if (parameters['backend_status'] !== undefined) {
-                    form['backend_status'] = parameters['backend_status'];
-                }
-
-                if (parameters['deleted'] !== undefined) {
-                    form['deleted'] = parameters['deleted'];
-                }
-
-                if (parameters['write_protect'] !== undefined) {
-                    form['write_protect'] = parameters['write_protect'];
-                }
-
-                if (parameters['lazy_blocked'] !== undefined) {
-                    form['lazy_blocked'] = parameters['lazy_blocked'];
-                }
-
-                if (parameters['no_sync'] !== undefined) {
-                    form['no_sync'] = parameters['no_sync'];
-                }
-
-                if (parameters['user'] !== undefined) {
-                    form['user'] = parameters['user'];
-                }
-
-                if (parameters['service'] !== undefined) {
-                    form['service'] = parameters['service'];
-                }
-
-                if (parameters['role'] !== undefined) {
-                    form['role'] = parameters['role'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xos#Service_Privilege_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xos.prototype.Service_Privilege_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xos/serviceprivileges/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xos.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-
-            return xos;
-        })();
-
-        return xos;
-    }]);
\ No newline at end of file
diff --git a/xos/core/xoslib/ngXosLib/api/ng-xoslib.js b/xos/core/xoslib/ngXosLib/api/ng-xoslib.js
deleted file mode 100644
index ff0380d..0000000
--- a/xos/core/xoslib/ngXosLib/api/ng-xoslib.js
+++ /dev/null
@@ -1,6177 +0,0 @@
-/*jshint -W069 */
-/*global angular:false */
-angular.module('xos.xoslib', [])
-    .factory('xoslib', ['$q', '$http', '$rootScope', function($q, $http, $rootScope) {
-        'use strict';
-
-        /**
-         * 
-         * @class xoslib
-         * @param {(string|object)} [domainOrOptions] - The project domain or options object. If object, see the object's optional properties.
-         * @param {string} [domainOrOptions.domain] - The project domain
-         * @param {string} [domainOrOptions.cache] - An angularjs cache implementation
-         * @param {object} [domainOrOptions.token] - auth token - object with value property and optional headerOrQueryName and isQuery properties
-         * @param {string} [cache] - An angularjs cache implementation
-         */
-        var xoslib = (function() {
-            function xoslib(options, cache) {
-                var domain = (typeof options === 'object') ? options.domain : options;
-                this.domain = typeof(domain) === 'string' ? domain : 'http://localhost:9999';
-                if (this.domain.length === 0) {
-                    throw new Error('Domain parameter must be specified as a string.');
-                }
-                cache = cache || ((typeof options === 'object') ? options.cache : cache);
-                this.cache = cache;
-            }
-
-            xoslib.prototype.$on = function($scope, path, handler) {
-                var url = domain + path;
-                $scope.$on(url, function() {
-                    handler();
-                });
-                return this;
-            };
-
-            xoslib.prototype.$broadcast = function(path) {
-                var url = domain + path;
-                //cache.remove(url);
-                $rootScope.$broadcast(url);
-                return this;
-            };
-
-            xoslib.transformRequest = function(obj) {
-                var str = [];
-                for (var p in obj) {
-                    var val = obj[p];
-                    if (angular.isArray(val)) {
-                        val.forEach(function(val) {
-                            str.push(encodeURIComponent(p) + "=" + encodeURIComponent(val));
-                        });
-                    } else {
-                        str.push(encodeURIComponent(p) + "=" + encodeURIComponent(val));
-                    }
-                }
-                return str.join("&");
-            };
-
-            /**
-             * 
-             * @method
-             * @name xoslib#Monitoring_Channel_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xoslib.prototype.Monitoring_Channel_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/monitoringchannel/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Monitoring_Channel_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} provider_service - 
-             * 
-             */
-            xoslib.prototype.Monitoring_Channel_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/monitoringchannel/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['provider_service'] !== undefined) {
-                    form['provider_service'] = parameters['provider_service'];
-                }
-
-                if (parameters['provider_service'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: provider_service'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Monitoring_Channel_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} provider_service - 
-             * 
-             */
-            xoslib.prototype.Monitoring_Channel_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/monitoringchannel/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['provider_service'] !== undefined) {
-                    form['provider_service'] = parameters['provider_service'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Monitoring_Channel_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xoslib.prototype.Monitoring_Channel_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/monitoringchannel/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Monitoring_Channel_List_GET
-             * 
-             */
-            xoslib.prototype.Monitoring_Channel_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/monitoringchannel/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Monitoring_Channel_List_POST
-             * @param {string} provider_service - 
-             * 
-             */
-            xoslib.prototype.Monitoring_Channel_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/monitoringchannel/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['provider_service'] !== undefined) {
-                    form['provider_service'] = parameters['provider_service'];
-                }
-
-                if (parameters['provider_service'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: provider_service'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Hpc_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xoslib.prototype.Hpc_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/hpcview/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Hpc_List_GET
-             * 
-             */
-            xoslib.prototype.Hpc_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/hpcview/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Tenant_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xoslib.prototype.Tenant_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/tenantview/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Tenant_List_GET
-             * 
-             */
-            xoslib.prototype.Tenant_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/tenantview/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Port_Forwarding_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xoslib.prototype.Port_Forwarding_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/portforwarding/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Port_Forwarding_List_GET
-             * 
-             */
-            xoslib.prototype.Port_Forwarding_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/portforwarding/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Ssh_Key_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xoslib.prototype.Ssh_Key_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/sshkeys/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Ssh_Key_List_GET
-             * 
-             */
-            xoslib.prototype.Ssh_Key_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/sshkeys/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Debug_get_vbng_dump
-             * 
-             */
-            xoslib.prototype.Cord_Debug_get_vbng_dump = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/rs/cord_debug/vbng_dump/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/cordsubscriber/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_Detail_PUT
-             * @param {string} pk - 
-             * @param {boolean} firewall_enable - 
-             * @param {string} firewall_rules - 
-             * @param {boolean} url_filter_enable - 
-             * @param {string} url_filter_rules - 
-             * @param {string} url_filter_level - 
-             * @param {boolean} vcpe_synced - 
-             * @param {boolean} cdn_enable - 
-             * @param {string} routeable_subnet - 
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/cordsubscriber/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['firewall_enable'] !== undefined) {
-                    form['firewall_enable'] = parameters['firewall_enable'];
-                }
-
-                if (parameters['firewall_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: firewall_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['firewall_rules'] !== undefined) {
-                    form['firewall_rules'] = parameters['firewall_rules'];
-                }
-
-                if (parameters['firewall_rules'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: firewall_rules'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_enable'] !== undefined) {
-                    form['url_filter_enable'] = parameters['url_filter_enable'];
-                }
-
-                if (parameters['url_filter_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url_filter_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_rules'] !== undefined) {
-                    form['url_filter_rules'] = parameters['url_filter_rules'];
-                }
-
-                if (parameters['url_filter_rules'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url_filter_rules'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_level'] !== undefined) {
-                    form['url_filter_level'] = parameters['url_filter_level'];
-                }
-
-                if (parameters['vcpe_synced'] !== undefined) {
-                    form['vcpe_synced'] = parameters['vcpe_synced'];
-                }
-
-                if (parameters['vcpe_synced'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: vcpe_synced'));
-                    return deferred.promise;
-                }
-
-                if (parameters['cdn_enable'] !== undefined) {
-                    form['cdn_enable'] = parameters['cdn_enable'];
-                }
-
-                if (parameters['cdn_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: cdn_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['routeable_subnet'] !== undefined) {
-                    form['routeable_subnet'] = parameters['routeable_subnet'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_Detail_PATCH
-             * @param {string} pk - 
-             * @param {boolean} firewall_enable - 
-             * @param {string} firewall_rules - 
-             * @param {boolean} url_filter_enable - 
-             * @param {string} url_filter_rules - 
-             * @param {string} url_filter_level - 
-             * @param {boolean} vcpe_synced - 
-             * @param {boolean} cdn_enable - 
-             * @param {string} routeable_subnet - 
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/cordsubscriber/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['firewall_enable'] !== undefined) {
-                    form['firewall_enable'] = parameters['firewall_enable'];
-                }
-
-                if (parameters['firewall_rules'] !== undefined) {
-                    form['firewall_rules'] = parameters['firewall_rules'];
-                }
-
-                if (parameters['url_filter_enable'] !== undefined) {
-                    form['url_filter_enable'] = parameters['url_filter_enable'];
-                }
-
-                if (parameters['url_filter_rules'] !== undefined) {
-                    form['url_filter_rules'] = parameters['url_filter_rules'];
-                }
-
-                if (parameters['url_filter_level'] !== undefined) {
-                    form['url_filter_level'] = parameters['url_filter_level'];
-                }
-
-                if (parameters['vcpe_synced'] !== undefined) {
-                    form['vcpe_synced'] = parameters['vcpe_synced'];
-                }
-
-                if (parameters['cdn_enable'] !== undefined) {
-                    form['cdn_enable'] = parameters['cdn_enable'];
-                }
-
-                if (parameters['routeable_subnet'] !== undefined) {
-                    form['routeable_subnet'] = parameters['routeable_subnet'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/cordsubscriber/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_List_GET
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/cordsubscriber/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_List_POST
-             * @param {boolean} firewall_enable - 
-             * @param {string} firewall_rules - 
-             * @param {boolean} url_filter_enable - 
-             * @param {string} url_filter_rules - 
-             * @param {string} url_filter_level - 
-             * @param {boolean} vcpe_synced - 
-             * @param {boolean} cdn_enable - 
-             * @param {string} routeable_subnet - 
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/cordsubscriber/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['firewall_enable'] !== undefined) {
-                    form['firewall_enable'] = parameters['firewall_enable'];
-                }
-
-                if (parameters['firewall_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: firewall_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['firewall_rules'] !== undefined) {
-                    form['firewall_rules'] = parameters['firewall_rules'];
-                }
-
-                if (parameters['firewall_rules'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: firewall_rules'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_enable'] !== undefined) {
-                    form['url_filter_enable'] = parameters['url_filter_enable'];
-                }
-
-                if (parameters['url_filter_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url_filter_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_rules'] !== undefined) {
-                    form['url_filter_rules'] = parameters['url_filter_rules'];
-                }
-
-                if (parameters['url_filter_rules'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url_filter_rules'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_level'] !== undefined) {
-                    form['url_filter_level'] = parameters['url_filter_level'];
-                }
-
-                if (parameters['vcpe_synced'] !== undefined) {
-                    form['vcpe_synced'] = parameters['vcpe_synced'];
-                }
-
-                if (parameters['vcpe_synced'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: vcpe_synced'));
-                    return deferred.promise;
-                }
-
-                if (parameters['cdn_enable'] !== undefined) {
-                    form['cdn_enable'] = parameters['cdn_enable'];
-                }
-
-                if (parameters['cdn_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: cdn_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['routeable_subnet'] !== undefined) {
-                    form['routeable_subnet'] = parameters['routeable_subnet'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_list
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_list = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/rs/subscriber/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_update
-             * @param {string} pk - 
-             * @param {boolean} firewall_enable - 
-             * @param {string} firewall_rules - 
-             * @param {boolean} url_filter_enable - 
-             * @param {string} url_filter_rules - 
-             * @param {string} url_filter_level - 
-             * @param {boolean} vcpe_synced - 
-             * @param {boolean} cdn_enable - 
-             * @param {string} routeable_subnet - 
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_update = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/rs/subscriber/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['firewall_enable'] !== undefined) {
-                    form['firewall_enable'] = parameters['firewall_enable'];
-                }
-
-                if (parameters['firewall_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: firewall_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['firewall_rules'] !== undefined) {
-                    form['firewall_rules'] = parameters['firewall_rules'];
-                }
-
-                if (parameters['firewall_rules'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: firewall_rules'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_enable'] !== undefined) {
-                    form['url_filter_enable'] = parameters['url_filter_enable'];
-                }
-
-                if (parameters['url_filter_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url_filter_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_rules'] !== undefined) {
-                    form['url_filter_rules'] = parameters['url_filter_rules'];
-                }
-
-                if (parameters['url_filter_rules'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url_filter_rules'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_level'] !== undefined) {
-                    form['url_filter_level'] = parameters['url_filter_level'];
-                }
-
-                if (parameters['vcpe_synced'] !== undefined) {
-                    form['vcpe_synced'] = parameters['vcpe_synced'];
-                }
-
-                if (parameters['vcpe_synced'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: vcpe_synced'));
-                    return deferred.promise;
-                }
-
-                if (parameters['cdn_enable'] !== undefined) {
-                    form['cdn_enable'] = parameters['cdn_enable'];
-                }
-
-                if (parameters['cdn_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: cdn_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['routeable_subnet'] !== undefined) {
-                    form['routeable_subnet'] = parameters['routeable_subnet'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_partial_update
-             * @param {string} pk - 
-             * @param {boolean} firewall_enable - 
-             * @param {string} firewall_rules - 
-             * @param {boolean} url_filter_enable - 
-             * @param {string} url_filter_rules - 
-             * @param {string} url_filter_level - 
-             * @param {boolean} vcpe_synced - 
-             * @param {boolean} cdn_enable - 
-             * @param {string} routeable_subnet - 
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_partial_update = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/rs/subscriber/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['firewall_enable'] !== undefined) {
-                    form['firewall_enable'] = parameters['firewall_enable'];
-                }
-
-                if (parameters['firewall_rules'] !== undefined) {
-                    form['firewall_rules'] = parameters['firewall_rules'];
-                }
-
-                if (parameters['url_filter_enable'] !== undefined) {
-                    form['url_filter_enable'] = parameters['url_filter_enable'];
-                }
-
-                if (parameters['url_filter_rules'] !== undefined) {
-                    form['url_filter_rules'] = parameters['url_filter_rules'];
-                }
-
-                if (parameters['url_filter_level'] !== undefined) {
-                    form['url_filter_level'] = parameters['url_filter_level'];
-                }
-
-                if (parameters['vcpe_synced'] !== undefined) {
-                    form['vcpe_synced'] = parameters['vcpe_synced'];
-                }
-
-                if (parameters['cdn_enable'] !== undefined) {
-                    form['cdn_enable'] = parameters['cdn_enable'];
-                }
-
-                if (parameters['routeable_subnet'] !== undefined) {
-                    form['routeable_subnet'] = parameters['routeable_subnet'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_update
-             * @param {string} pk - 
-             * @param {boolean} firewall_enable - 
-             * @param {string} firewall_rules - 
-             * @param {boolean} url_filter_enable - 
-             * @param {string} url_filter_rules - 
-             * @param {string} url_filter_level - 
-             * @param {boolean} vcpe_synced - 
-             * @param {boolean} cdn_enable - 
-             * @param {string} routeable_subnet - 
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_update = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/rs/subscriber/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['firewall_enable'] !== undefined) {
-                    form['firewall_enable'] = parameters['firewall_enable'];
-                }
-
-                if (parameters['firewall_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: firewall_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['firewall_rules'] !== undefined) {
-                    form['firewall_rules'] = parameters['firewall_rules'];
-                }
-
-                if (parameters['firewall_rules'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: firewall_rules'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_enable'] !== undefined) {
-                    form['url_filter_enable'] = parameters['url_filter_enable'];
-                }
-
-                if (parameters['url_filter_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url_filter_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_rules'] !== undefined) {
-                    form['url_filter_rules'] = parameters['url_filter_rules'];
-                }
-
-                if (parameters['url_filter_rules'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url_filter_rules'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_level'] !== undefined) {
-                    form['url_filter_level'] = parameters['url_filter_level'];
-                }
-
-                if (parameters['vcpe_synced'] !== undefined) {
-                    form['vcpe_synced'] = parameters['vcpe_synced'];
-                }
-
-                if (parameters['vcpe_synced'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: vcpe_synced'));
-                    return deferred.promise;
-                }
-
-                if (parameters['cdn_enable'] !== undefined) {
-                    form['cdn_enable'] = parameters['cdn_enable'];
-                }
-
-                if (parameters['cdn_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: cdn_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['routeable_subnet'] !== undefined) {
-                    form['routeable_subnet'] = parameters['routeable_subnet'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_destroy
-             * @param {string} pk - 
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_destroy = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/rs/subscriber/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_retrieve
-             * @param {string} pk - 
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_retrieve = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/rs/subscriber/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_get_vcpe_synced
-             * @param {string} pk - 
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_get_vcpe_synced = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/rs/subscriber/{pk}/vcpe_synced/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_get_url_filter
-             * @param {string} pk - 
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_get_url_filter = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/rs/subscriber/{pk}/url_filter/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_set_url_filter
-             * @param {string} pk - 
-             * @param {string} level - 
-             * @param {boolean} firewall_enable - 
-             * @param {string} firewall_rules - 
-             * @param {boolean} url_filter_enable - 
-             * @param {string} url_filter_rules - 
-             * @param {string} url_filter_level - 
-             * @param {boolean} vcpe_synced - 
-             * @param {boolean} cdn_enable - 
-             * @param {string} routeable_subnet - 
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_set_url_filter = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/rs/subscriber/{pk}/url_filter/{level}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                path = path.replace('{level}', parameters['level']);
-
-                if (parameters['level'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: level'));
-                    return deferred.promise;
-                }
-
-                if (parameters['firewall_enable'] !== undefined) {
-                    form['firewall_enable'] = parameters['firewall_enable'];
-                }
-
-                if (parameters['firewall_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: firewall_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['firewall_rules'] !== undefined) {
-                    form['firewall_rules'] = parameters['firewall_rules'];
-                }
-
-                if (parameters['firewall_rules'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: firewall_rules'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_enable'] !== undefined) {
-                    form['url_filter_enable'] = parameters['url_filter_enable'];
-                }
-
-                if (parameters['url_filter_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url_filter_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_rules'] !== undefined) {
-                    form['url_filter_rules'] = parameters['url_filter_rules'];
-                }
-
-                if (parameters['url_filter_rules'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url_filter_rules'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_level'] !== undefined) {
-                    form['url_filter_level'] = parameters['url_filter_level'];
-                }
-
-                if (parameters['vcpe_synced'] !== undefined) {
-                    form['vcpe_synced'] = parameters['vcpe_synced'];
-                }
-
-                if (parameters['vcpe_synced'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: vcpe_synced'));
-                    return deferred.promise;
-                }
-
-                if (parameters['cdn_enable'] !== undefined) {
-                    form['cdn_enable'] = parameters['cdn_enable'];
-                }
-
-                if (parameters['cdn_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: cdn_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['routeable_subnet'] !== undefined) {
-                    form['routeable_subnet'] = parameters['routeable_subnet'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_get_services
-             * @param {string} pk - 
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_get_services = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/rs/subscriber/{pk}/services/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_get_service
-             * @param {string} pk - 
-             * @param {string} service - 
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_get_service = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/rs/subscriber/{pk}/services/{service}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                path = path.replace('{service}', parameters['service']);
-
-                if (parameters['service'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: service'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_enable_service
-             * @param {string} pk - 
-             * @param {string} service - 
-             * @param {boolean} firewall_enable - 
-             * @param {string} firewall_rules - 
-             * @param {boolean} url_filter_enable - 
-             * @param {string} url_filter_rules - 
-             * @param {string} url_filter_level - 
-             * @param {boolean} vcpe_synced - 
-             * @param {boolean} cdn_enable - 
-             * @param {string} routeable_subnet - 
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_enable_service = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/rs/subscriber/{pk}/services/{service}/true/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                path = path.replace('{service}', parameters['service']);
-
-                if (parameters['service'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: service'));
-                    return deferred.promise;
-                }
-
-                if (parameters['firewall_enable'] !== undefined) {
-                    form['firewall_enable'] = parameters['firewall_enable'];
-                }
-
-                if (parameters['firewall_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: firewall_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['firewall_rules'] !== undefined) {
-                    form['firewall_rules'] = parameters['firewall_rules'];
-                }
-
-                if (parameters['firewall_rules'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: firewall_rules'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_enable'] !== undefined) {
-                    form['url_filter_enable'] = parameters['url_filter_enable'];
-                }
-
-                if (parameters['url_filter_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url_filter_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_rules'] !== undefined) {
-                    form['url_filter_rules'] = parameters['url_filter_rules'];
-                }
-
-                if (parameters['url_filter_rules'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url_filter_rules'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_level'] !== undefined) {
-                    form['url_filter_level'] = parameters['url_filter_level'];
-                }
-
-                if (parameters['vcpe_synced'] !== undefined) {
-                    form['vcpe_synced'] = parameters['vcpe_synced'];
-                }
-
-                if (parameters['vcpe_synced'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: vcpe_synced'));
-                    return deferred.promise;
-                }
-
-                if (parameters['cdn_enable'] !== undefined) {
-                    form['cdn_enable'] = parameters['cdn_enable'];
-                }
-
-                if (parameters['cdn_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: cdn_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['routeable_subnet'] !== undefined) {
-                    form['routeable_subnet'] = parameters['routeable_subnet'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_disable_service
-             * @param {string} pk - 
-             * @param {string} service - 
-             * @param {boolean} firewall_enable - 
-             * @param {string} firewall_rules - 
-             * @param {boolean} url_filter_enable - 
-             * @param {string} url_filter_rules - 
-             * @param {string} url_filter_level - 
-             * @param {boolean} vcpe_synced - 
-             * @param {boolean} cdn_enable - 
-             * @param {string} routeable_subnet - 
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_disable_service = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/rs/subscriber/{pk}/services/{service}/false/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                path = path.replace('{service}', parameters['service']);
-
-                if (parameters['service'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: service'));
-                    return deferred.promise;
-                }
-
-                if (parameters['firewall_enable'] !== undefined) {
-                    form['firewall_enable'] = parameters['firewall_enable'];
-                }
-
-                if (parameters['firewall_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: firewall_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['firewall_rules'] !== undefined) {
-                    form['firewall_rules'] = parameters['firewall_rules'];
-                }
-
-                if (parameters['firewall_rules'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: firewall_rules'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_enable'] !== undefined) {
-                    form['url_filter_enable'] = parameters['url_filter_enable'];
-                }
-
-                if (parameters['url_filter_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url_filter_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_rules'] !== undefined) {
-                    form['url_filter_rules'] = parameters['url_filter_rules'];
-                }
-
-                if (parameters['url_filter_rules'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url_filter_rules'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_level'] !== undefined) {
-                    form['url_filter_level'] = parameters['url_filter_level'];
-                }
-
-                if (parameters['vcpe_synced'] !== undefined) {
-                    form['vcpe_synced'] = parameters['vcpe_synced'];
-                }
-
-                if (parameters['vcpe_synced'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: vcpe_synced'));
-                    return deferred.promise;
-                }
-
-                if (parameters['cdn_enable'] !== undefined) {
-                    form['cdn_enable'] = parameters['cdn_enable'];
-                }
-
-                if (parameters['cdn_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: cdn_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['routeable_subnet'] !== undefined) {
-                    form['routeable_subnet'] = parameters['routeable_subnet'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_create_user
-             * @param {string} pk - 
-             * @param {boolean} firewall_enable - 
-             * @param {string} firewall_rules - 
-             * @param {boolean} url_filter_enable - 
-             * @param {string} url_filter_rules - 
-             * @param {string} url_filter_level - 
-             * @param {boolean} vcpe_synced - 
-             * @param {boolean} cdn_enable - 
-             * @param {string} routeable_subnet - 
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_create_user = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/rs/subscriber/{pk}/users/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['firewall_enable'] !== undefined) {
-                    form['firewall_enable'] = parameters['firewall_enable'];
-                }
-
-                if (parameters['firewall_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: firewall_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['firewall_rules'] !== undefined) {
-                    form['firewall_rules'] = parameters['firewall_rules'];
-                }
-
-                if (parameters['firewall_rules'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: firewall_rules'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_enable'] !== undefined) {
-                    form['url_filter_enable'] = parameters['url_filter_enable'];
-                }
-
-                if (parameters['url_filter_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url_filter_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_rules'] !== undefined) {
-                    form['url_filter_rules'] = parameters['url_filter_rules'];
-                }
-
-                if (parameters['url_filter_rules'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url_filter_rules'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_level'] !== undefined) {
-                    form['url_filter_level'] = parameters['url_filter_level'];
-                }
-
-                if (parameters['vcpe_synced'] !== undefined) {
-                    form['vcpe_synced'] = parameters['vcpe_synced'];
-                }
-
-                if (parameters['vcpe_synced'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: vcpe_synced'));
-                    return deferred.promise;
-                }
-
-                if (parameters['cdn_enable'] !== undefined) {
-                    form['cdn_enable'] = parameters['cdn_enable'];
-                }
-
-                if (parameters['cdn_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: cdn_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['routeable_subnet'] !== undefined) {
-                    form['routeable_subnet'] = parameters['routeable_subnet'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_get_users
-             * @param {string} pk - 
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_get_users = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/rs/subscriber/{pk}/users/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_clear_users
-             * @param {string} pk - 
-             * @param {boolean} firewall_enable - 
-             * @param {string} firewall_rules - 
-             * @param {boolean} url_filter_enable - 
-             * @param {string} url_filter_rules - 
-             * @param {string} url_filter_level - 
-             * @param {boolean} vcpe_synced - 
-             * @param {boolean} cdn_enable - 
-             * @param {string} routeable_subnet - 
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_clear_users = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/rs/subscriber/{pk}/users/clearusers/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['firewall_enable'] !== undefined) {
-                    form['firewall_enable'] = parameters['firewall_enable'];
-                }
-
-                if (parameters['firewall_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: firewall_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['firewall_rules'] !== undefined) {
-                    form['firewall_rules'] = parameters['firewall_rules'];
-                }
-
-                if (parameters['firewall_rules'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: firewall_rules'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_enable'] !== undefined) {
-                    form['url_filter_enable'] = parameters['url_filter_enable'];
-                }
-
-                if (parameters['url_filter_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url_filter_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_rules'] !== undefined) {
-                    form['url_filter_rules'] = parameters['url_filter_rules'];
-                }
-
-                if (parameters['url_filter_rules'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url_filter_rules'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_level'] !== undefined) {
-                    form['url_filter_level'] = parameters['url_filter_level'];
-                }
-
-                if (parameters['vcpe_synced'] !== undefined) {
-                    form['vcpe_synced'] = parameters['vcpe_synced'];
-                }
-
-                if (parameters['vcpe_synced'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: vcpe_synced'));
-                    return deferred.promise;
-                }
-
-                if (parameters['cdn_enable'] !== undefined) {
-                    form['cdn_enable'] = parameters['cdn_enable'];
-                }
-
-                if (parameters['cdn_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: cdn_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['routeable_subnet'] !== undefined) {
-                    form['routeable_subnet'] = parameters['routeable_subnet'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_clear_users
-             * @param {string} pk - 
-             * @param {boolean} firewall_enable - 
-             * @param {string} firewall_rules - 
-             * @param {boolean} url_filter_enable - 
-             * @param {string} url_filter_rules - 
-             * @param {string} url_filter_level - 
-             * @param {boolean} vcpe_synced - 
-             * @param {boolean} cdn_enable - 
-             * @param {string} routeable_subnet - 
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_clear_users = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/rs/subscriber/{pk}/users/clearusers/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['firewall_enable'] !== undefined) {
-                    form['firewall_enable'] = parameters['firewall_enable'];
-                }
-
-                if (parameters['firewall_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: firewall_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['firewall_rules'] !== undefined) {
-                    form['firewall_rules'] = parameters['firewall_rules'];
-                }
-
-                if (parameters['firewall_rules'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: firewall_rules'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_enable'] !== undefined) {
-                    form['url_filter_enable'] = parameters['url_filter_enable'];
-                }
-
-                if (parameters['url_filter_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url_filter_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_rules'] !== undefined) {
-                    form['url_filter_rules'] = parameters['url_filter_rules'];
-                }
-
-                if (parameters['url_filter_rules'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url_filter_rules'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_level'] !== undefined) {
-                    form['url_filter_level'] = parameters['url_filter_level'];
-                }
-
-                if (parameters['vcpe_synced'] !== undefined) {
-                    form['vcpe_synced'] = parameters['vcpe_synced'];
-                }
-
-                if (parameters['vcpe_synced'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: vcpe_synced'));
-                    return deferred.promise;
-                }
-
-                if (parameters['cdn_enable'] !== undefined) {
-                    form['cdn_enable'] = parameters['cdn_enable'];
-                }
-
-                if (parameters['cdn_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: cdn_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['routeable_subnet'] !== undefined) {
-                    form['routeable_subnet'] = parameters['routeable_subnet'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_clear_users
-             * @param {string} pk - 
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_clear_users = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/rs/subscriber/{pk}/users/clearusers/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_create_user
-             * @param {string} pk - 
-             * @param {boolean} firewall_enable - 
-             * @param {string} firewall_rules - 
-             * @param {boolean} url_filter_enable - 
-             * @param {string} url_filter_rules - 
-             * @param {string} url_filter_level - 
-             * @param {boolean} vcpe_synced - 
-             * @param {boolean} cdn_enable - 
-             * @param {string} routeable_subnet - 
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_create_user = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/rs/subscriber/{pk}/users/newuser/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['firewall_enable'] !== undefined) {
-                    form['firewall_enable'] = parameters['firewall_enable'];
-                }
-
-                if (parameters['firewall_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: firewall_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['firewall_rules'] !== undefined) {
-                    form['firewall_rules'] = parameters['firewall_rules'];
-                }
-
-                if (parameters['firewall_rules'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: firewall_rules'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_enable'] !== undefined) {
-                    form['url_filter_enable'] = parameters['url_filter_enable'];
-                }
-
-                if (parameters['url_filter_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url_filter_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_rules'] !== undefined) {
-                    form['url_filter_rules'] = parameters['url_filter_rules'];
-                }
-
-                if (parameters['url_filter_rules'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url_filter_rules'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_level'] !== undefined) {
-                    form['url_filter_level'] = parameters['url_filter_level'];
-                }
-
-                if (parameters['vcpe_synced'] !== undefined) {
-                    form['vcpe_synced'] = parameters['vcpe_synced'];
-                }
-
-                if (parameters['vcpe_synced'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: vcpe_synced'));
-                    return deferred.promise;
-                }
-
-                if (parameters['cdn_enable'] !== undefined) {
-                    form['cdn_enable'] = parameters['cdn_enable'];
-                }
-
-                if (parameters['cdn_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: cdn_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['routeable_subnet'] !== undefined) {
-                    form['routeable_subnet'] = parameters['routeable_subnet'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_create_user
-             * @param {string} pk - 
-             * @param {boolean} firewall_enable - 
-             * @param {string} firewall_rules - 
-             * @param {boolean} url_filter_enable - 
-             * @param {string} url_filter_rules - 
-             * @param {string} url_filter_level - 
-             * @param {boolean} vcpe_synced - 
-             * @param {boolean} cdn_enable - 
-             * @param {string} routeable_subnet - 
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_create_user = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/rs/subscriber/{pk}/users/newuser/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['firewall_enable'] !== undefined) {
-                    form['firewall_enable'] = parameters['firewall_enable'];
-                }
-
-                if (parameters['firewall_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: firewall_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['firewall_rules'] !== undefined) {
-                    form['firewall_rules'] = parameters['firewall_rules'];
-                }
-
-                if (parameters['firewall_rules'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: firewall_rules'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_enable'] !== undefined) {
-                    form['url_filter_enable'] = parameters['url_filter_enable'];
-                }
-
-                if (parameters['url_filter_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url_filter_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_rules'] !== undefined) {
-                    form['url_filter_rules'] = parameters['url_filter_rules'];
-                }
-
-                if (parameters['url_filter_rules'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url_filter_rules'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_level'] !== undefined) {
-                    form['url_filter_level'] = parameters['url_filter_level'];
-                }
-
-                if (parameters['vcpe_synced'] !== undefined) {
-                    form['vcpe_synced'] = parameters['vcpe_synced'];
-                }
-
-                if (parameters['vcpe_synced'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: vcpe_synced'));
-                    return deferred.promise;
-                }
-
-                if (parameters['cdn_enable'] !== undefined) {
-                    form['cdn_enable'] = parameters['cdn_enable'];
-                }
-
-                if (parameters['cdn_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: cdn_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['routeable_subnet'] !== undefined) {
-                    form['routeable_subnet'] = parameters['routeable_subnet'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_delete_user
-             * @param {string} pk - 
-             * @param {string} uid - 
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_delete_user = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/rs/subscriber/{pk}/users/{uid}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                path = path.replace('{uid}', parameters['uid']);
-
-                if (parameters['uid'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: uid'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_get_user_level
-             * @param {string} pk - 
-             * @param {string} uid - 
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_get_user_level = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/rs/subscriber/{pk}/users/{uid}/url_filter/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                path = path.replace('{uid}', parameters['uid']);
-
-                if (parameters['uid'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: uid'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_set_user_level
-             * @param {string} pk - 
-             * @param {string} uid - 
-             * @param {string} level - 
-             * @param {boolean} firewall_enable - 
-             * @param {string} firewall_rules - 
-             * @param {boolean} url_filter_enable - 
-             * @param {string} url_filter_rules - 
-             * @param {string} url_filter_level - 
-             * @param {boolean} vcpe_synced - 
-             * @param {boolean} cdn_enable - 
-             * @param {string} routeable_subnet - 
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_set_user_level = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/rs/subscriber/{pk}/users/{uid}/url_filter/{level}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                path = path.replace('{uid}', parameters['uid']);
-
-                if (parameters['uid'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: uid'));
-                    return deferred.promise;
-                }
-
-                path = path.replace('{level}', parameters['level']);
-
-                if (parameters['level'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: level'));
-                    return deferred.promise;
-                }
-
-                if (parameters['firewall_enable'] !== undefined) {
-                    form['firewall_enable'] = parameters['firewall_enable'];
-                }
-
-                if (parameters['firewall_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: firewall_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['firewall_rules'] !== undefined) {
-                    form['firewall_rules'] = parameters['firewall_rules'];
-                }
-
-                if (parameters['firewall_rules'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: firewall_rules'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_enable'] !== undefined) {
-                    form['url_filter_enable'] = parameters['url_filter_enable'];
-                }
-
-                if (parameters['url_filter_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url_filter_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_rules'] !== undefined) {
-                    form['url_filter_rules'] = parameters['url_filter_rules'];
-                }
-
-                if (parameters['url_filter_rules'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url_filter_rules'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_level'] !== undefined) {
-                    form['url_filter_level'] = parameters['url_filter_level'];
-                }
-
-                if (parameters['vcpe_synced'] !== undefined) {
-                    form['vcpe_synced'] = parameters['vcpe_synced'];
-                }
-
-                if (parameters['vcpe_synced'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: vcpe_synced'));
-                    return deferred.promise;
-                }
-
-                if (parameters['cdn_enable'] !== undefined) {
-                    form['cdn_enable'] = parameters['cdn_enable'];
-                }
-
-                if (parameters['cdn_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: cdn_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['routeable_subnet'] !== undefined) {
-                    form['routeable_subnet'] = parameters['routeable_subnet'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_get_bbsdump
-             * @param {string} pk - 
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_get_bbsdump = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/rs/subscriber/{pk}/bbsdump/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_initdemo
-             * @param {boolean} firewall_enable - 
-             * @param {string} firewall_rules - 
-             * @param {boolean} url_filter_enable - 
-             * @param {string} url_filter_rules - 
-             * @param {string} url_filter_level - 
-             * @param {boolean} vcpe_synced - 
-             * @param {boolean} cdn_enable - 
-             * @param {string} routeable_subnet - 
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_initdemo = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/rs/initdemo/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['firewall_enable'] !== undefined) {
-                    form['firewall_enable'] = parameters['firewall_enable'];
-                }
-
-                if (parameters['firewall_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: firewall_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['firewall_rules'] !== undefined) {
-                    form['firewall_rules'] = parameters['firewall_rules'];
-                }
-
-                if (parameters['firewall_rules'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: firewall_rules'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_enable'] !== undefined) {
-                    form['url_filter_enable'] = parameters['url_filter_enable'];
-                }
-
-                if (parameters['url_filter_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url_filter_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_rules'] !== undefined) {
-                    form['url_filter_rules'] = parameters['url_filter_rules'];
-                }
-
-                if (parameters['url_filter_rules'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: url_filter_rules'));
-                    return deferred.promise;
-                }
-
-                if (parameters['url_filter_level'] !== undefined) {
-                    form['url_filter_level'] = parameters['url_filter_level'];
-                }
-
-                if (parameters['vcpe_synced'] !== undefined) {
-                    form['vcpe_synced'] = parameters['vcpe_synced'];
-                }
-
-                if (parameters['vcpe_synced'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: vcpe_synced'));
-                    return deferred.promise;
-                }
-
-                if (parameters['cdn_enable'] !== undefined) {
-                    form['cdn_enable'] = parameters['cdn_enable'];
-                }
-
-                if (parameters['cdn_enable'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: cdn_enable'));
-                    return deferred.promise;
-                }
-
-                if (parameters['routeable_subnet'] !== undefined) {
-                    form['routeable_subnet'] = parameters['routeable_subnet'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_initdemo
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_initdemo = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/rs/initdemo/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_ssiddetail
-             * @param {string} ssid - 
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_ssiddetail = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/rs/subidlookup/{ssid}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{ssid}', parameters['ssid']);
-
-                if (parameters['ssid'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: ssid'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_ssidlist
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_ssidlist = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/rs/subidlookup/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_Subscriber_get_vbng_mapping
-             * 
-             */
-            xoslib.prototype.Cord_Subscriber_get_vbng_mapping = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/rs/vbng_mapping/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_User_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xoslib.prototype.Cord_User_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/corduser/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_User_Detail_PUT
-             * @param {string} pk - 
-             * 
-             */
-            xoslib.prototype.Cord_User_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/corduser/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_User_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xoslib.prototype.Cord_User_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/corduser/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_User_List_GET
-             * 
-             */
-            xoslib.prototype.Cord_User_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/corduser/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Cord_User_List_POST
-             * 
-             */
-            xoslib.prototype.Cord_User_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/corduser/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Volt_Tenant_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xoslib.prototype.Volt_Tenant_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/volttenant/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Volt_Tenant_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} provider_service - 
-             * @param {string} service_specific_id - 
-             * @param {string} vlan_id - 
-             * 
-             */
-            xoslib.prototype.Volt_Tenant_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/volttenant/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['provider_service'] !== undefined) {
-                    form['provider_service'] = parameters['provider_service'];
-                }
-
-                if (parameters['provider_service'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: provider_service'));
-                    return deferred.promise;
-                }
-
-                if (parameters['service_specific_id'] !== undefined) {
-                    form['service_specific_id'] = parameters['service_specific_id'];
-                }
-
-                if (parameters['service_specific_id'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: service_specific_id'));
-                    return deferred.promise;
-                }
-
-                if (parameters['vlan_id'] !== undefined) {
-                    form['vlan_id'] = parameters['vlan_id'];
-                }
-
-                if (parameters['vlan_id'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: vlan_id'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Volt_Tenant_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} provider_service - 
-             * @param {string} service_specific_id - 
-             * @param {string} vlan_id - 
-             * 
-             */
-            xoslib.prototype.Volt_Tenant_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/volttenant/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['provider_service'] !== undefined) {
-                    form['provider_service'] = parameters['provider_service'];
-                }
-
-                if (parameters['service_specific_id'] !== undefined) {
-                    form['service_specific_id'] = parameters['service_specific_id'];
-                }
-
-                if (parameters['vlan_id'] !== undefined) {
-                    form['vlan_id'] = parameters['vlan_id'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Volt_Tenant_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xoslib.prototype.Volt_Tenant_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/volttenant/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Volt_Tenant_List_GET
-             * 
-             */
-            xoslib.prototype.Volt_Tenant_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/volttenant/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Volt_Tenant_List_POST
-             * @param {string} provider_service - 
-             * @param {string} service_specific_id - 
-             * @param {string} vlan_id - 
-             * 
-             */
-            xoslib.prototype.Volt_Tenant_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/volttenant/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['provider_service'] !== undefined) {
-                    form['provider_service'] = parameters['provider_service'];
-                }
-
-                if (parameters['provider_service'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: provider_service'));
-                    return deferred.promise;
-                }
-
-                if (parameters['service_specific_id'] !== undefined) {
-                    form['service_specific_id'] = parameters['service_specific_id'];
-                }
-
-                if (parameters['service_specific_id'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: service_specific_id'));
-                    return deferred.promise;
-                }
-
-                if (parameters['vlan_id'] !== undefined) {
-                    form['vlan_id'] = parameters['vlan_id'];
-                }
-
-                if (parameters['vlan_id'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: vlan_id'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Slice_Plus_Detail_GET
-             * @param {string} pk - 
-             * 
-             */
-            xoslib.prototype.Slice_Plus_Detail_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/slicesplus/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Slice_Plus_Detail_PUT
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} name - The Name of the Slice
-             * @param {boolean} enabled - Status for this Slice
-             * @param {boolean} omf_friendly - 
-             * @param {string} description - High level description of the slice and expected activities
-             * @param {string} slice_url - 
-             * @param {string} site - The Site this Slice belongs to
-             * @param {integer} max_instances - 
-             * @param {string} service - 
-             * @param {string} network - 
-             * @param {string} mount_data_sets - 
-             * @param {string} default_image - 
-             * @param {string} default_flavor - 
-             * @param {string} serviceClass - 
-             * @param {string} creator - 
-             * @param {string} network_ports - 
-             * @param {string} site_allocation - 
-             * @param {string} site_ready - 
-             * @param {string} users - 
-             * @param {string} user_names - 
-             * 
-             */
-            xoslib.prototype.Slice_Plus_Detail_PUT = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/slicesplus/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters['omf_friendly'] !== undefined) {
-                    form['omf_friendly'] = parameters['omf_friendly'];
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['slice_url'] !== undefined) {
-                    form['slice_url'] = parameters['slice_url'];
-                }
-
-                if (parameters['site'] !== undefined) {
-                    form['site'] = parameters['site'];
-                }
-
-                if (parameters['site'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: site'));
-                    return deferred.promise;
-                }
-
-                if (parameters['max_instances'] !== undefined) {
-                    form['max_instances'] = parameters['max_instances'];
-                }
-
-                if (parameters['max_instances'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: max_instances'));
-                    return deferred.promise;
-                }
-
-                if (parameters['service'] !== undefined) {
-                    form['service'] = parameters['service'];
-                }
-
-                if (parameters['network'] !== undefined) {
-                    form['network'] = parameters['network'];
-                }
-
-                if (parameters['mount_data_sets'] !== undefined) {
-                    form['mount_data_sets'] = parameters['mount_data_sets'];
-                }
-
-                if (parameters['default_image'] !== undefined) {
-                    form['default_image'] = parameters['default_image'];
-                }
-
-                if (parameters['default_flavor'] !== undefined) {
-                    form['default_flavor'] = parameters['default_flavor'];
-                }
-
-                if (parameters['serviceClass'] !== undefined) {
-                    form['serviceClass'] = parameters['serviceClass'];
-                }
-
-                if (parameters['creator'] !== undefined) {
-                    form['creator'] = parameters['creator'];
-                }
-
-                if (parameters['network_ports'] !== undefined) {
-                    form['network_ports'] = parameters['network_ports'];
-                }
-
-                if (parameters['site_allocation'] !== undefined) {
-                    form['site_allocation'] = parameters['site_allocation'];
-                }
-
-                if (parameters['site_ready'] !== undefined) {
-                    form['site_ready'] = parameters['site_ready'];
-                }
-
-                if (parameters['users'] !== undefined) {
-                    form['users'] = parameters['users'];
-                }
-
-                if (parameters['user_names'] !== undefined) {
-                    form['user_names'] = parameters['user_names'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PUT',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Slice_Plus_Detail_PATCH
-             * @param {string} pk - 
-             * @param {string} enacted - 
-             * @param {string} name - The Name of the Slice
-             * @param {boolean} enabled - Status for this Slice
-             * @param {boolean} omf_friendly - 
-             * @param {string} description - High level description of the slice and expected activities
-             * @param {string} slice_url - 
-             * @param {string} site - The Site this Slice belongs to
-             * @param {integer} max_instances - 
-             * @param {string} service - 
-             * @param {string} network - 
-             * @param {string} mount_data_sets - 
-             * @param {string} default_image - 
-             * @param {string} default_flavor - 
-             * @param {string} serviceClass - 
-             * @param {string} creator - 
-             * @param {string} network_ports - 
-             * @param {string} site_allocation - 
-             * @param {string} site_ready - 
-             * @param {string} users - 
-             * @param {string} user_names - 
-             * 
-             */
-            xoslib.prototype.Slice_Plus_Detail_PATCH = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/slicesplus/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters['omf_friendly'] !== undefined) {
-                    form['omf_friendly'] = parameters['omf_friendly'];
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['slice_url'] !== undefined) {
-                    form['slice_url'] = parameters['slice_url'];
-                }
-
-                if (parameters['site'] !== undefined) {
-                    form['site'] = parameters['site'];
-                }
-
-                if (parameters['max_instances'] !== undefined) {
-                    form['max_instances'] = parameters['max_instances'];
-                }
-
-                if (parameters['service'] !== undefined) {
-                    form['service'] = parameters['service'];
-                }
-
-                if (parameters['network'] !== undefined) {
-                    form['network'] = parameters['network'];
-                }
-
-                if (parameters['mount_data_sets'] !== undefined) {
-                    form['mount_data_sets'] = parameters['mount_data_sets'];
-                }
-
-                if (parameters['default_image'] !== undefined) {
-                    form['default_image'] = parameters['default_image'];
-                }
-
-                if (parameters['default_flavor'] !== undefined) {
-                    form['default_flavor'] = parameters['default_flavor'];
-                }
-
-                if (parameters['serviceClass'] !== undefined) {
-                    form['serviceClass'] = parameters['serviceClass'];
-                }
-
-                if (parameters['creator'] !== undefined) {
-                    form['creator'] = parameters['creator'];
-                }
-
-                if (parameters['network_ports'] !== undefined) {
-                    form['network_ports'] = parameters['network_ports'];
-                }
-
-                if (parameters['site_allocation'] !== undefined) {
-                    form['site_allocation'] = parameters['site_allocation'];
-                }
-
-                if (parameters['site_ready'] !== undefined) {
-                    form['site_ready'] = parameters['site_ready'];
-                }
-
-                if (parameters['users'] !== undefined) {
-                    form['users'] = parameters['users'];
-                }
-
-                if (parameters['user_names'] !== undefined) {
-                    form['user_names'] = parameters['user_names'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'PATCH',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Slice_Plus_Detail_DELETE
-             * @param {string} pk - 
-             * 
-             */
-            xoslib.prototype.Slice_Plus_Detail_DELETE = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/slicesplus/{pk}/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                path = path.replace('{pk}', parameters['pk']);
-
-                if (parameters['pk'] === undefined) {
-                    deferred.reject(new Error('Missing required path parameter: pk'));
-                    return deferred.promise;
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'DELETE',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Slice_Plus_List_GET
-             * 
-             */
-            xoslib.prototype.Slice_Plus_List_GET = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/slicesplus/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var cached = parameters.$cache && parameters.$cache.get(url);
-                if (cached !== undefined && parameters.$refresh !== true) {
-                    deferred.resolve(cached);
-                    return deferred.promise;
-                }
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'GET',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-            /**
-             * 
-             * @method
-             * @name xoslib#Slice_Plus_List_POST
-             * @param {string} enacted - 
-             * @param {string} name - The Name of the Slice
-             * @param {boolean} enabled - Status for this Slice
-             * @param {boolean} omf_friendly - 
-             * @param {string} description - High level description of the slice and expected activities
-             * @param {string} slice_url - 
-             * @param {string} site - The Site this Slice belongs to
-             * @param {integer} max_instances - 
-             * @param {string} service - 
-             * @param {string} network - 
-             * @param {string} mount_data_sets - 
-             * @param {string} default_image - 
-             * @param {string} default_flavor - 
-             * @param {string} serviceClass - 
-             * @param {string} creator - 
-             * @param {string} network_ports - 
-             * @param {string} site_allocation - 
-             * @param {string} site_ready - 
-             * @param {string} users - 
-             * @param {string} user_names - 
-             * 
-             */
-            xoslib.prototype.Slice_Plus_List_POST = function(parameters) {
-                if (parameters === undefined) {
-                    parameters = {};
-                }
-                var deferred = $q.defer();
-
-                var domain = this.domain;
-                var path = '/xoslib/slicesplus/';
-
-                var body;
-                var queryParameters = {};
-                var headers = {};
-                var form = {};
-
-                if (parameters['enacted'] !== undefined) {
-                    form['enacted'] = parameters['enacted'];
-                }
-
-                if (parameters['name'] !== undefined) {
-                    form['name'] = parameters['name'];
-                }
-
-                if (parameters['name'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: name'));
-                    return deferred.promise;
-                }
-
-                if (parameters['enabled'] !== undefined) {
-                    form['enabled'] = parameters['enabled'];
-                }
-
-                if (parameters['omf_friendly'] !== undefined) {
-                    form['omf_friendly'] = parameters['omf_friendly'];
-                }
-
-                if (parameters['description'] !== undefined) {
-                    form['description'] = parameters['description'];
-                }
-
-                if (parameters['slice_url'] !== undefined) {
-                    form['slice_url'] = parameters['slice_url'];
-                }
-
-                if (parameters['site'] !== undefined) {
-                    form['site'] = parameters['site'];
-                }
-
-                if (parameters['site'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: site'));
-                    return deferred.promise;
-                }
-
-                if (parameters['max_instances'] !== undefined) {
-                    form['max_instances'] = parameters['max_instances'];
-                }
-
-                if (parameters['max_instances'] === undefined) {
-                    deferred.reject(new Error('Missing required form parameter: max_instances'));
-                    return deferred.promise;
-                }
-
-                if (parameters['service'] !== undefined) {
-                    form['service'] = parameters['service'];
-                }
-
-                if (parameters['network'] !== undefined) {
-                    form['network'] = parameters['network'];
-                }
-
-                if (parameters['mount_data_sets'] !== undefined) {
-                    form['mount_data_sets'] = parameters['mount_data_sets'];
-                }
-
-                if (parameters['default_image'] !== undefined) {
-                    form['default_image'] = parameters['default_image'];
-                }
-
-                if (parameters['default_flavor'] !== undefined) {
-                    form['default_flavor'] = parameters['default_flavor'];
-                }
-
-                if (parameters['serviceClass'] !== undefined) {
-                    form['serviceClass'] = parameters['serviceClass'];
-                }
-
-                if (parameters['creator'] !== undefined) {
-                    form['creator'] = parameters['creator'];
-                }
-
-                if (parameters['network_ports'] !== undefined) {
-                    form['network_ports'] = parameters['network_ports'];
-                }
-
-                if (parameters['site_allocation'] !== undefined) {
-                    form['site_allocation'] = parameters['site_allocation'];
-                }
-
-                if (parameters['site_ready'] !== undefined) {
-                    form['site_ready'] = parameters['site_ready'];
-                }
-
-                if (parameters['users'] !== undefined) {
-                    form['users'] = parameters['users'];
-                }
-
-                if (parameters['user_names'] !== undefined) {
-                    form['user_names'] = parameters['user_names'];
-                }
-
-                if (parameters.$queryParameters) {
-                    Object.keys(parameters.$queryParameters)
-                        .forEach(function(parameterName) {
-                            var parameter = parameters.$queryParameters[parameterName];
-                            queryParameters[parameterName] = parameter;
-                        });
-                }
-
-                var url = domain + path;
-                var options = {
-                    timeout: parameters.$timeout,
-                    method: 'POST',
-                    url: url,
-                    params: queryParameters,
-                    data: body,
-                    headers: headers
-                };
-                if (Object.keys(form).length > 0) {
-                    options.data = form;
-                    options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
-                    options.transformRequest = xoslib.transformRequest;
-                }
-                $http(options)
-                    .success(function(data, status, headers, config) {
-                        deferred.resolve(data);
-                        if (parameters.$cache !== undefined) {
-                            parameters.$cache.put(url, data, parameters.$cacheItemOpts ? parameters.$cacheItemOpts : {});
-                        }
-                    })
-                    .error(function(data, status, headers, config) {
-                        deferred.reject({
-                            status: status,
-                            headers: headers,
-                            config: config,
-                            body: data
-                        });
-                    });
-
-                return deferred.promise;
-            };
-
-            return xoslib;
-        })();
-
-        return xoslib;
-    }]);
\ No newline at end of file
