diff --git a/views/ngXosLib/api/.gitignore b/views/ngXosLib/api/.gitignore
deleted file mode 100644
index e69de29..0000000
--- a/views/ngXosLib/api/.gitignore
+++ /dev/null
diff --git a/views/ngXosLib/api/ng-hpcapi.js b/views/ngXosLib/api/ng-hpcapi.js
deleted file mode 100755
index 762b304..0000000
--- a/views/ngXosLib/api/ng-hpcapi.js
+++ /dev/null
@@ -1,5440 +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';
-                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/views/ngXosLib/api/ng-xos.js b/views/ngXosLib/api/ng-xos.js
deleted file mode 100755
index 20ea691..0000000
--- a/views/ngXosLib/api/ng-xos.js
+++ /dev/null
@@ -1,39957 +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';
-                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/views/ngXosLib/api/ng-xoslib.js b/views/ngXosLib/api/ng-xoslib.js
deleted file mode 100755
index 16b5d9b..0000000
--- a/views/ngXosLib/api/ng-xoslib.js
+++ /dev/null
@@ -1,6174 +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';
-                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
diff --git a/views/ngXosLib/apiTemplates/custom-angular-class.mustache b/views/ngXosLib/apiTemplates/custom-angular-class.mustache
deleted file mode 100644
index c92a870..0000000
--- a/views/ngXosLib/apiTemplates/custom-angular-class.mustache
+++ /dev/null
@@ -1,82 +0,0 @@
-/*jshint -W069 */
-/*global angular:false */
-angular.module('{{&moduleName}}', [])
-.factory('{{&className}}', ['$q', '$http', '$rootScope', function($q, $http, $rootScope){
-    'use strict';
-
-    /**
-     * {{&description}}
-     * @class {{&className}}
-     * @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 {{&className}} = (function(){
-        function {{&className}}(options, cache){
-            var domain = (typeof options === 'object') ? options.domain : options;
-            this.domain = typeof(domain) === 'string' ? domain : '{{&domain}}';
-            cache = cache || ((typeof options === 'object') ? options.cache : cache);
-            this.cache = cache;
-            {{#isSecure}}
-                this.token = (typeof options === 'object') ? (options.token ? options.token : {}) : {};
-            {{/isSecure}}
-        }
-
-        {{&className}}.prototype.$on = function($scope, path, handler){
-            var url = domain + path;
-            $scope.$on(url, function(){
-                handler();
-            });
-            return this;
-        };
-
-        {{&className}}.prototype.$broadcast = function(path){
-            var url = domain + path;
-            //cache.remove(url);
-            $rootScope.$broadcast(url);
-            return this;
-        };
-
-        {{&className}}.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("&");
-        };
-
-        {{#isSecure}}
-            /**
-             * Set Token
-             * @method
-             * @name {{&className}}#setToken
-             * @param {string} value - token's value
-             * @param {string} headerOrQueryName - the header or query name to send the token at
-             * @param {boolean} isQuery - true if send the token as query param, otherwise, send as header param
-             *
-             */
-            {{&className}}.prototype.setToken = function (value, headerOrQueryName, isQuery) {
-                this.token.value = value;
-                this.token.headerOrQueryName = headerOrQueryName;
-                this.token.isQuery = isQuery;
-            };
-        {{/isSecure}}
-
-        {{#methods}}
-            {{> method}}
-        {{/methods}}
-
-  return {{&className}};
-    })();
-
-    return {{&className}};
-}]);
diff --git a/views/ngXosLib/apigen/blueprintToNgResource.js b/views/ngXosLib/apigen/blueprintToNgResource.js
index 20f2869..2a3cde3 100644
--- a/views/ngXosLib/apigen/blueprintToNgResource.js
+++ b/views/ngXosLib/apigen/blueprintToNgResource.js
@@ -6,6 +6,8 @@
 const _ = require('lodash');
 const chalk = require('chalk');
 const Handlebars = require('handlebars');
+const util = require('util');
+const path = require('path');
 
 P.promisifyAll(fs);
 P.promisifyAll(protagonist);
@@ -49,7 +51,7 @@
       ngModule: angualarModuleName,
       resources: loopApiEndpoint(d.content)
     };
-    fs.writeFileSync(`../xosHelpers/src/services/rest/${formatTitle(d.meta.title)}.js`, handlebarsTemplate(data));
+    fs.writeFileSync(path.join(__dirname, `../xosHelpers/src/services/rest/${formatTitle(d.meta.title)}.js`), handlebarsTemplate(data));
   });
 
   console.info(chalk.green.bold(`Api Generated`));
@@ -58,16 +60,17 @@
 
 // Loop the top level definitions
 const loopApiDefinitions = (defs) => {
+  // console.log(util.inspect(defs, false, null));
   _.forEach(defs, d => loopApiGroups(d.content));
 };
 
 let handlebarsTemplate;
 
 // read blueprint docs and parse
-fs.readFileAsync('./ngResourceTemplate.handlebars', 'utf8')
+fs.readFileAsync(path.join(__dirname, './ngResourceTemplate.handlebars'), 'utf8')
 .then((template) => {
   handlebarsTemplate = Handlebars.compile(template);
-  return fs.readFileAsync('../../../xos/tests/api/apiary.apib', 'utf8')
+  return fs.readFileAsync(path.join(__dirname, '../../../xos/tests/api/apiary.apib'), 'utf8')
 })
 .then(data => protagonist.parseAsync(data))
 .then(result => loopApiDefinitions(result.content))
diff --git a/views/ngXosLib/apigen/ngResourceTemplate.handlebars b/views/ngXosLib/apigen/ngResourceTemplate.handlebars
index d326a51..6048669 100644
--- a/views/ngXosLib/apigen/ngResourceTemplate.handlebars
+++ b/views/ngXosLib/apigen/ngResourceTemplate.handlebars
@@ -1,14 +1,16 @@
-'use strict';
-{{#if description}}
+(function() {
+  'use strict';
+  {{#if description}}
 
-/*
- * {{description}}
- */
-{{/if}}
+  /*
+   * {{description}}
+   */
+  {{/if}}
 
-angular.module('{{ngModule}}')
-{{#each resources}}
-.service('{{name}}', function($resource){
-  return $resource('{{param.href}}'{{#if param.name}}, { {{param.name}}: '@id' }{{/if}});
-})
-{{/each}}
\ No newline at end of file
+  angular.module('{{ngModule}}')
+  {{#each resources}}
+  .service('{{name}}', function($resource){
+    return $resource('{{param.href}}'{{#if param.name}}, { {{param.name}}: '@id' }{{/if}});
+  })
+  {{/each}}
+})();
\ No newline at end of file
diff --git a/views/ngXosLib/generator-xos/app/templates/bower.json b/views/ngXosLib/generator-xos/app/templates/bower.json
index 667a7ac..d8f456f 100644
--- a/views/ngXosLib/generator-xos/app/templates/bower.json
+++ b/views/ngXosLib/generator-xos/app/templates/bower.json
@@ -24,6 +24,6 @@
     "angular-cookies": "1.4.7",
     "angular-resource": "1.4.7",
     "ng-lodash": "0.3.0",
-    "bootstrap-css": "2.3.2"
+    "bootstrap-css": "3.3.6"
   }
 }
diff --git a/views/ngXosLib/generator-xos/app/templates/karma.conf.js b/views/ngXosLib/generator-xos/app/templates/karma.conf.js
index 83d3f63..4123be9 100644
--- a/views/ngXosLib/generator-xos/app/templates/karma.conf.js
+++ b/views/ngXosLib/generator-xos/app/templates/karma.conf.js
@@ -26,8 +26,8 @@
 
     // list of files / patterns to load in the browser
     files: bowerComponents.concat([
-      '../../static/js/xosApi.js',
-      '../../static/js/vendor/ngXosHelpers.js',
+      '../../../xos/core/xoslib/static/js/vendor/ngXosVendor.js',
+      '../../../xos/core/xoslib/static/js/vendor/ngXosHelpers.js',
       'src/js/**/*.js',
       'spec/**/*.mock.js',
       'spec/**/*.test.js',
diff --git a/views/ngXosLib/generator-xos/app/templates/package.json b/views/ngXosLib/generator-xos/app/templates/package.json
index 7c0a016..b0f77f9 100644
--- a/views/ngXosLib/generator-xos/app/templates/package.json
+++ b/views/ngXosLib/generator-xos/app/templates/package.json
@@ -8,6 +8,7 @@
     "prebuild": "npm install && bower install",
     "build": "gulp",
     "test": "karma start",
+    "test:ci": "karma start --single-run",
     "lint": "eslint src/js/"
   },
   "keywords": [
@@ -19,28 +20,44 @@
   "license": "MIT",
   "dependencies": {},
   "devDependencies": {
+    "autoprefixer": "^6.3.3",
     "browser-sync": "^2.9.11",
+    "css-mqpacker": "^4.0.0",
+    "csswring": "^4.2.1",
     "del": "^2.0.2",
+    "easy-mocker": "^1.2.0",
+    "eslint": "^1.8.0",
+    "eslint-plugin-angular": "linkmesrl/eslint-plugin-angular",
     "gulp": "^3.9.0",
     "gulp-angular-filesort": "^1.1.1",
     "gulp-angular-templatecache": "^1.8.0",
     "gulp-babel": "^5.3.0",
     "gulp-concat": "^2.6.0",
+    "gulp-concat-util": "^0.5.5",
+    "gulp-eslint": "^1.0.0",
     "gulp-inject": "^3.0.0",
     "gulp-minify-html": "^1.0.4",
+    "gulp-ng-annotate": "^1.1.0",
+    "gulp-postcss": "^6.0.1",
     "gulp-rename": "^1.2.2",
     "gulp-replace": "^0.5.4",
     "gulp-sass": "^2.2.0",
     "gulp-uglify": "^1.4.2",
     "http-proxy": "^1.12.0",
+    "ink-docstrap": "^0.5.2",
+    "jasmine-core": "~2.3.4",
+    "karma": "^0.13.14",
+    "karma-babel-preprocessor": "~5.2.2",
+    "karma-coverage": "^0.5.3",
+    "karma-jasmine": "~0.3.6",
+    "karma-mocha-reporter": "~1.1.1",
+    "karma-ng-html2js-preprocessor": "^0.2.0",
+    "karma-phantomjs-launcher": "~0.2.1",
+    "lodash": "^3.10.1",
+    "phantomjs": "^1.9.19",
     "proxy-middleware": "^0.15.0",
     "run-sequence": "^1.1.4",
     "wiredep": "^3.0.0-beta",
-    "wrench": "^1.5.8",
-    "gulp-ng-annotate": "^1.1.0",
-    "lodash": "^3.10.1",
-    "eslint": "^1.8.0",
-    "eslint-plugin-angular": "linkmesrl/eslint-plugin-angular",
-    "gulp-eslint": "^1.0.0"
+    "wrench": "^1.5.8"
   }
 }
diff --git a/views/ngXosLib/generator-xos/app/templates/spec/sample.test.js b/views/ngXosLib/generator-xos/app/templates/spec/sample.test.js
index 10a74ad..b00fa5e 100644
--- a/views/ngXosLib/generator-xos/app/templates/spec/sample.test.js
+++ b/views/ngXosLib/generator-xos/app/templates/spec/sample.test.js
@@ -11,7 +11,7 @@
     
     httpBackend = $httpBackend;
     // Setting up mock request
-    $httpBackend.expectGET('/xos/users/?no_hyperlinks=1').respond([
+    $httpBackend.expectGET('/api/core/users/?no_hyperlinks=1').respond([
       {
         email: '<%= user.email %>',
         firstname: '<%= user.firstname %>',
diff --git a/views/ngXosLib/generator-xos/app/templates/src/index.html b/views/ngXosLib/generator-xos/app/templates/src/index.html
index f546c21..eeb0dec 100644
--- a/views/ngXosLib/generator-xos/app/templates/src/index.html
+++ b/views/ngXosLib/generator-xos/app/templates/src/index.html
@@ -4,7 +4,7 @@
 <!-- inject:css -->
 <!-- endinject -->
 
-<div ng-app="xos.<%= name %>" id="xos<%= fileName %>" class="container">
+<div ng-app="xos.<%= name %>" id="xos<%= fileName %>" class="container-fluid">
     <div ui-view></div>
 </div>
 
diff --git a/views/ngXosLib/generator-xos/app/templates/src/templates/users-list.tpl.html b/views/ngXosLib/generator-xos/app/templates/src/templates/users-list.tpl.html
index 2983ad0..03be487 100644
--- a/views/ngXosLib/generator-xos/app/templates/src/templates/users-list.tpl.html
+++ b/views/ngXosLib/generator-xos/app/templates/src/templates/users-list.tpl.html
@@ -3,12 +3,12 @@
   <p>This is only an example view.</p>
 </div>
 <div class="row">
-  <div class="span4">Email</div>
-  <div class="span4">First Name</div>
-  <div class="span4">Last Name</div>
+  <div class="col-xs-4">Email</div>
+  <div class="col-xs-4">First Name</div>
+  <div class="col-xs-4">Last Name</div>
 </div>  
 <div class="row" ng-repeat="user in vm.users">
-  <div class="span4">{{user.email}}</div>
-  <div class="span4">{{user.firstname}}</div>
-  <div class="span4">{{user.lastname}}</div>
+  <div class="col-xs-4">{{user.email}}</div>
+  <div class="col-xs-4">{{user.firstname}}</div>
+  <div class="col-xs-4">{{user.lastname}}</div>
 </div>  
\ No newline at end of file
diff --git a/views/ngXosLib/package.json b/views/ngXosLib/package.json
index b2d092d..8804013 100644
--- a/views/ngXosLib/package.json
+++ b/views/ngXosLib/package.json
@@ -5,7 +5,7 @@
   "main": "index.js",
   "scripts": {
     "test": "karma start",
-    "apigen": "node xos-resource-generator.js",
+    "apigen": "node apigen/blueprintToNgResource.js",
     "swagger": "node xos-swagger-def.js",
     "apidoc": "jsdoc api/ng-xos.js api/ng-xoslib.js api/ng-hpcapi.js -d api/docs",
     "build": "gulp vendor && gulp helpers"
@@ -24,6 +24,7 @@
   },
   "devDependencies": {
     "babel-preset-es2015": "^6.6.0",
+    "concat": "^2.0.0",
     "gulp": "^3.9.0",
     "gulp-angular-filesort": "^1.1.1",
     "gulp-concat": "^2.6.0",
diff --git a/views/ngXosLib/xos-resource-generator.js b/views/ngXosLib/xos-resource-generator.js
deleted file mode 100644
index b24bf9b..0000000
--- a/views/ngXosLib/xos-resource-generator.js
+++ /dev/null
@@ -1,99 +0,0 @@
-'use strict';
-
-var fs = require('fs');
-var CodeGen = require('swagger-js-codegen').CodeGen;
-var fetchSchema = require('fetch-swagger-schema');
-var P = require('bluebird');
-var chalk = require('chalk');
-var concat = require('concat')
-
-/////////////
-// HELPERS //
-/////////////
-
-var fetchSwagger = P.promisify(function(url, done){
-  fetchSchema(url, function(error, schema){
-    if(error) {
-      return done(error);
-    }
-    done(null, schema);
-  });
-});
-
-// Write to file promisified
-var writeToFile = P.promisify(function(file, content, done) {
-  fs.writeFile(file, content, function(err) {
-    if(err) {
-        return done(err);
-    }
-
-    done(null, file + ' has been saved');
-  }); 
-});
-
-var concatFiles = P.promisify(function(files, dest, done){
-  concat(files, dest, function (error) {
-    if(error){
-      return done(error);
-    }
-    done();
-  })
-});
-
-////////////////////
-// generator loop //
-////////////////////
-
-P.coroutine(function*(){
-  
-  var generatedFiles = [];
-
-  console.log(chalk.green('Generating APIs '));
-
-  let mainDef = yield fetchSwagger('http://localhost:9999/docs/api-docs/');
-
-  for(let i = 0; i < mainDef.apis.length; i++){
-    
-    const path = mainDef.apis[i].path.replace('/', '');
-  
-    process.stdout.write(chalk.green(`Starting ${path} generation `));
-    
-    let loader = setInterval(function(){
-      process.stdout.write(chalk.green('.'));
-    }, 500);
-
-
-    let def = yield fetchSwagger(`http://localhost:9999/docs/api-docs/${path}`);
-    yield writeToFile(`api/ng-${path}.js`, CodeGen.getAngularCode({ 
-      moduleName: `xos.${path}`, 
-      className: `${path}`, 
-      swagger: def,
-      lint: false,
-      template: {
-        class: fs.readFileSync('apiTemplates/custom-angular-class.mustache', 'utf-8'),
-        method: fs.readFileSync('node_modules/swagger-js-codegen/templates/method.mustache', 'utf-8'),
-        request: fs.readFileSync('node_modules/swagger-js-codegen/templates/angular-request.mustache', 'utf-8')
-    }
-    }));
-  
-    generatedFiles.push(`api/ng-${path}.js`);
-
-    clearInterval(loader);
-    process.stdout.write('\n');
-  }
-
-  // TODO rewrite concat to minify API
-  // evaluate to use gulp instead to manage this
-  // at least minify
-  yield concatFiles(generatedFiles, '../static/js/xosApi.js');
-
-  console.log(chalk.green('APIs Ready!'));
-
-  process.exit();
-
-})()
-.catch(function(e){
-  process.stdout.write('\n');
-  console.error(e);
-  process.exit(e.code);
-});
diff --git a/views/ngXosLib/xos-swagger-def.js b/views/ngXosLib/xos-swagger-def.js
deleted file mode 100644
index 64db936..0000000
--- a/views/ngXosLib/xos-swagger-def.js
+++ /dev/null
@@ -1,96 +0,0 @@
-// This was generating the files needed from https://github.com/signalfx/swagger-angular-client
-// But this module is not parsing the format in which our Swagger is generating JSON files
-
-'use strict';
-
-var fs = require('fs');
-var CodeGen = require('swagger-js-codegen').CodeGen;
-var fetchSchema = require('fetch-swagger-schema');
-var P = require('bluebird');
-var chalk = require('chalk');
-var concat = require('concat')
-
-/////////////
-// HELPERS //
-/////////////
-
-var fetchSwagger = P.promisify(function(url, done){
-  fetchSchema(url, function(error, schema){
-    if(error) {
-      return done(error);
-    }
-    done(null, schema);
-  });
-});
-
-// Write to file promisified
-var writeToFile = P.promisify(function(file, content, done) {
-  fs.writeFile(file, content, function(err) {
-    if(err) {
-        return done(err);
-    }
-
-    done(null, file + ' has been saved');
-  }); 
-});
-
-var concatFiles = P.promisify(function(files, dest, done){
-  concat(files, dest, function (error) {
-    if(error){
-      return done(error);
-    }
-    done();
-  })
-});
-
-////////////////////
-// generator loop //
-////////////////////
-
-P.coroutine(function*(){
-  
-  var generatedFiles = [];
-
-  console.log(chalk.green('Generating APIs '));
-
-  let mainDef = yield fetchSwagger('http://localhost:9999/docs/api-docs/');
-
-  yield writeToFile(`api/ngXosApi-runtime.js`, `window.XosApi = ${JSON.stringify(mainDef)}`)
-
-  for(let i = 0; i < mainDef.apis.length; i++){
-    
-    const path = mainDef.apis[i].path.replace('/', '');
-  
-    process.stdout.write(chalk.green(`Starting ${path} generation `));
-    
-    let loader = setInterval(function(){
-      process.stdout.write(chalk.green('.'));
-    }, 500);
-
-
-    let def = yield fetchSwagger(`http://localhost:9999/docs/api-docs/${path}`);
-    
-    yield writeToFile(`api/ng-${path}.json`, JSON.stringify(def));
-    yield writeToFile(`api/ng-${path}.js`, `window.${path}Api = ${JSON.stringify(def)}`)
-  
-    generatedFiles.push(`api/ng-${path}.js`);
-
-    clearInterval(loader);
-    process.stdout.write('\n');
-  }
-
-  // TODO rewrite concat to minify API
-  // evaluate to use gulp instead to manage this
-  // at least minify
-  yield concatFiles(generatedFiles, '../static/js/xosApi.js');
-
-  console.log(chalk.green('APIs Ready!'));
-
-  process.exit();
-
-})()
-.catch(function(e){
-  process.stdout.write('\n');
-  console.error(e);
-  process.exit(e.code);
-});
diff --git a/views/ngXosLib/xosHelpers/src/services/api.services.js b/views/ngXosLib/xosHelpers/src/services/api.services.js
deleted file mode 100644
index c7384f8..0000000
--- a/views/ngXosLib/xosHelpers/src/services/api.services.js
+++ /dev/null
@@ -1,32 +0,0 @@
-(function() {
-  'use strict';
-
-    angular
-        .module('xos.helpers')
-        .service('XosApi', xosApi)
-        .service('XoslibApi', xoslibApi)
-        .service('HpcApi', hpcApi);
-
-    var xosApiCache, xoslibApiCache, hpcApiCache;
-
-    function xosApi(xos) { 
-      if(!xosApiCache){
-        xosApiCache = new xos({domain: ''});
-      }
-      return xosApiCache;
-    }
-
-    function xoslibApi(xoslib) { 
-      if(!xoslibApiCache){
-        xoslibApiCache = new xoslib({domain: ''});
-      }
-      return xoslibApiCache;
-    }
-
-    function hpcApi(hpcapi) { 
-      if(!hpcApiCache){
-        hpcApiCache = new hpcapi({domain: ''});
-      }
-      return hpcApiCache;
-    }
-})();
diff --git a/views/ngXosLib/xosHelpers/src/services/rest/ONOS-Apps.js b/views/ngXosLib/xosHelpers/src/services/rest/ONOS-Apps.js
index 8634f2b..5d0d1ba 100644
--- a/views/ngXosLib/xosHelpers/src/services/rest/ONOS-Apps.js
+++ b/views/ngXosLib/xosHelpers/src/services/rest/ONOS-Apps.js
@@ -1,6 +1,8 @@
-'use strict';
+(function() {
+  'use strict';
 
-angular.module('xos.helpers')
-.service('ONOS-App-Collection', function($resource){
-  return $resource('/api/tenant/onos/app/');
-})
+  angular.module('xos.helpers')
+  .service('ONOS-App-Collection', function($resource){
+    return $resource('/api/tenant/onos/app/');
+  })
+})();
\ No newline at end of file
diff --git a/views/ngXosLib/xosHelpers/src/services/rest/ONOS-Services.js b/views/ngXosLib/xosHelpers/src/services/rest/ONOS-Services.js
index a2302fb..724ce9a 100644
--- a/views/ngXosLib/xosHelpers/src/services/rest/ONOS-Services.js
+++ b/views/ngXosLib/xosHelpers/src/services/rest/ONOS-Services.js
@@ -1,11 +1,13 @@
-'use strict';
+(function() {
+  'use strict';
 
-/*
- * List of the active onos services
+  /*
+   * List of the active onos services
 
- */
+   */
 
-angular.module('xos.helpers')
-.service('ONOS-Services-Collection', function($resource){
-  return $resource('/api/service/onos/');
-})
+  angular.module('xos.helpers')
+  .service('ONOS-Services-Collection', function($resource){
+    return $resource('/api/service/onos/');
+  })
+})();
\ No newline at end of file
diff --git a/views/ngXosLib/xosHelpers/src/services/rest/Subscribers.js b/views/ngXosLib/xosHelpers/src/services/rest/Subscribers.js
index df7ee4e..2605c2a 100644
--- a/views/ngXosLib/xosHelpers/src/services/rest/Subscribers.js
+++ b/views/ngXosLib/xosHelpers/src/services/rest/Subscribers.js
@@ -1,29 +1,31 @@
-'use strict';
+(function() {
+  'use strict';
 
-/*
- * Resource related to the CORD Subscribers.
+  /*
+   * Resource related to the CORD Subscribers.
 
- */
+   */
 
-angular.module('xos.helpers')
-.service('Subscribers', function($resource){
-  return $resource('/api/tenant/cord/subscriber/:subscriber_id/', { subscriber_id: '@id' });
-})
-.service('Subscriber-features', function($resource){
-  return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/', { subscriber_id: '@id' });
-})
-.service('Subscriber-features-uplink_speed', function($resource){
-  return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/uplink_speed/', { subscriber_id: '@id' });
-})
-.service('Subscriber-features-downlink_speed', function($resource){
-  return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/downlink_speed/', { subscriber_id: '@id' });
-})
-.service('Subscriber-features-cdn', function($resource){
-  return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/cdn/', { subscriber_id: '@id' });
-})
-.service('Subscriber-features-uverse', function($resource){
-  return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/uverse/', { subscriber_id: '@id' });
-})
-.service('Subscriber-features-status', function($resource){
-  return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/status/', { subscriber_id: '@id' });
-})
+  angular.module('xos.helpers')
+  .service('Subscribers', function($resource){
+    return $resource('/api/tenant/cord/subscriber/:subscriber_id/', { subscriber_id: '@id' });
+  })
+  .service('Subscriber-features', function($resource){
+    return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/', { subscriber_id: '@id' });
+  })
+  .service('Subscriber-features-uplink_speed', function($resource){
+    return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/uplink_speed/', { subscriber_id: '@id' });
+  })
+  .service('Subscriber-features-downlink_speed', function($resource){
+    return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/downlink_speed/', { subscriber_id: '@id' });
+  })
+  .service('Subscriber-features-cdn', function($resource){
+    return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/cdn/', { subscriber_id: '@id' });
+  })
+  .service('Subscriber-features-uverse', function($resource){
+    return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/uverse/', { subscriber_id: '@id' });
+  })
+  .service('Subscriber-features-status', function($resource){
+    return $resource('/api/tenant/cord/subscriber/:subscriber_id/features/status/', { subscriber_id: '@id' });
+  })
+})();
\ No newline at end of file
diff --git a/views/ngXosLib/xosHelpers/src/services/rest/Truckroll.js b/views/ngXosLib/xosHelpers/src/services/rest/Truckroll.js
index 7f1f9b5..e7a631e 100644
--- a/views/ngXosLib/xosHelpers/src/services/rest/Truckroll.js
+++ b/views/ngXosLib/xosHelpers/src/services/rest/Truckroll.js
@@ -1,11 +1,13 @@
-'use strict';
+(function() {
+  'use strict';
 
-/*
- * Virtual Truckroll, enable to perform basic test on user connectivity such as ping, traceroute and tcpdump.
+  /*
+   * Virtual Truckroll, enable to perform basic test on user connectivity such as ping, traceroute and tcpdump.
 
- */
+   */
 
-angular.module('xos.helpers')
-.service('Truckroll-Collection', function($resource){
-  return $resource('/api/tenant/truckroll/:truckroll_id/', { truckroll_id: '@id' });
-})
+  angular.module('xos.helpers')
+  .service('Truckroll-Collection', function($resource){
+    return $resource('/api/tenant/truckroll/:truckroll_id/', { truckroll_id: '@id' });
+  })
+})();
\ No newline at end of file
diff --git a/views/ngXosLib/xosHelpers/src/services/rest/Users.js b/views/ngXosLib/xosHelpers/src/services/rest/Users.js
index 2e8f552..b8301c7 100644
--- a/views/ngXosLib/xosHelpers/src/services/rest/Users.js
+++ b/views/ngXosLib/xosHelpers/src/services/rest/Users.js
@@ -1,11 +1,13 @@
-'use strict';
+(function() {
+  'use strict';
 
-/*
- * List of the XOS users
+  /*
+   * List of the XOS users
 
- */
+   */
 
-angular.module('xos.helpers')
-.service('Users', function($resource){
-  return $resource('/api/core/users/');
-})
+  angular.module('xos.helpers')
+  .service('Users', function($resource){
+    return $resource('/api/core/users/');
+  })
+})();
\ No newline at end of file
diff --git a/views/ngXosLib/xosHelpers/src/services/rest/vOLT.js b/views/ngXosLib/xosHelpers/src/services/rest/vOLT.js
index e69f8ea..8bac542 100644
--- a/views/ngXosLib/xosHelpers/src/services/rest/vOLT.js
+++ b/views/ngXosLib/xosHelpers/src/services/rest/vOLT.js
@@ -1,11 +1,13 @@
-'use strict';
+(function() {
+  'use strict';
 
-/*
- * OLT devices aggregate a set of subscriber connections
+  /*
+   * OLT devices aggregate a set of subscriber connections
 
- */
+   */
 
-angular.module('xos.helpers')
-.service('vOLT-Collection', function($resource){
-  return $resource('/api/tenant/cord/volt/:volt_id/', { volt_id: '@id' });
-})
+  angular.module('xos.helpers')
+  .service('vOLT-Collection', function($resource){
+    return $resource('/api/tenant/cord/volt/:volt_id/', { volt_id: '@id' });
+  })
+})();
\ No newline at end of file
diff --git a/views/ngXosLib/xosHelpers/src/services/rest/vSG.js b/views/ngXosLib/xosHelpers/src/services/rest/vSG.js
index 04ffa0e..b6af52c 100644
--- a/views/ngXosLib/xosHelpers/src/services/rest/vSG.js
+++ b/views/ngXosLib/xosHelpers/src/services/rest/vSG.js
@@ -1,6 +1,8 @@
-'use strict';
+(function() {
+  'use strict';
 
-angular.module('xos.helpers')
-.service('vSG-Collection', function($resource){
-  return $resource('/api/service/vsg/');
-})
+  angular.module('xos.helpers')
+  .service('vSG-Collection', function($resource){
+    return $resource('/api/service/vsg/');
+  })
+})();
\ No newline at end of file
