diff --git a/static/js/restangular.js b/static/js/restangular.js
new file mode 100644
index 0000000..b59b25f
--- /dev/null
+++ b/static/js/restangular.js
@@ -0,0 +1,1452 @@
+/**
+ * Restful Resources service for AngularJS apps
+ * @version v1.6.1 - 2017-01-06 * @link https://github.com/mgonto/restangular
+ * @author Martin Gontovnikas <martin@gon.to>
+ * @license MIT License, http://www.opensource.org/licenses/MIT
+ */(function(root, factory) {
+  /* global define, require */
+  // https://github.com/umdjs/umd/blob/master/templates/returnExports.js
+  if (typeof define === 'function' && define.amd) {
+    define(['lodash', 'angular'], factory);
+  } else if (typeof module === 'object' && module.exports) {
+    module.exports = factory(require('lodash'), require('angular'));
+  } else {
+    // No global export, Restangular will register itself as Angular.js module
+    factory(root._, root.angular);
+  }
+}(this, function(_, angular) {
+
+  var restangular = angular.module('restangular', []);
+
+  restangular.provider('Restangular', function() {
+    // Configuration
+    var Configurer = {};
+    Configurer.init = function(object, config) {
+      object.configuration = config;
+
+      /**
+       * Those are HTTP safe methods for which there is no need to pass any data with the request.
+       */
+      var safeMethods = ['get', 'head', 'options', 'trace', 'getlist'];
+      config.isSafe = function(operation) {
+        return _.includes(safeMethods, operation.toLowerCase());
+      };
+
+      var absolutePattern = /^https?:\/\//i;
+      config.isAbsoluteUrl = function(string) {
+        return _.isUndefined(config.absoluteUrl) || _.isNull(config.absoluteUrl) ?
+          string && absolutePattern.test(string) :
+          config.absoluteUrl;
+      };
+
+      config.absoluteUrl = _.isUndefined(config.absoluteUrl) ? true : config.absoluteUrl;
+      object.setSelfLinkAbsoluteUrl = function(value) {
+        config.absoluteUrl = value;
+      };
+      /**
+       * This is the BaseURL to be used with Restangular
+       */
+      config.baseUrl = _.isUndefined(config.baseUrl) ? '' : config.baseUrl;
+      object.setBaseUrl = function(newBaseUrl) {
+        config.baseUrl = /\/$/.test(newBaseUrl) ?
+          newBaseUrl.substring(0, newBaseUrl.length - 1) :
+          newBaseUrl;
+        return this;
+      };
+
+      /**
+       * Sets the extra fields to keep from the parents
+       */
+      config.extraFields = config.extraFields || [];
+      object.setExtraFields = function(newExtraFields) {
+        config.extraFields = newExtraFields;
+        return this;
+      };
+
+      /**
+       * Some default $http parameter to be used in EVERY call
+       **/
+      config.defaultHttpFields = config.defaultHttpFields || {};
+      object.setDefaultHttpFields = function(values) {
+        config.defaultHttpFields = values;
+        return this;
+      };
+
+      /**
+       * Always return plain data, no restangularized object
+       **/
+      config.plainByDefault = config.plainByDefault || false;
+      object.setPlainByDefault = function(value) {
+        config.plainByDefault = value === true ? true : false;
+        return this;
+      };
+
+      config.withHttpValues = function(httpLocalConfig, obj) {
+        return _.defaults(obj, httpLocalConfig, config.defaultHttpFields);
+      };
+
+      config.encodeIds = _.isUndefined(config.encodeIds) ? true : config.encodeIds;
+      object.setEncodeIds = function(encode) {
+        config.encodeIds = encode;
+      };
+
+      config.defaultRequestParams = config.defaultRequestParams || {
+        get: {},
+        post: {},
+        put: {},
+        remove: {},
+        common: {}
+      };
+
+      object.setDefaultRequestParams = function(param1, param2) {
+        var methods = [],
+          params = param2 || param1;
+        if (!_.isUndefined(param2)) {
+          if (_.isArray(param1)) {
+            methods = param1;
+          } else {
+            methods.push(param1);
+          }
+        } else {
+          methods.push('common');
+        }
+
+        _.each(methods, function(method) {
+          config.defaultRequestParams[method] = params;
+        });
+        return this;
+      };
+
+      object.requestParams = config.defaultRequestParams;
+
+      config.defaultHeaders = config.defaultHeaders || {};
+      object.setDefaultHeaders = function(headers) {
+        config.defaultHeaders = headers;
+        object.defaultHeaders = config.defaultHeaders;
+        return this;
+      };
+
+      object.defaultHeaders = config.defaultHeaders;
+
+      /**
+       * Method overriders will set which methods are sent via POST with an X-HTTP-Method-Override
+       **/
+      config.methodOverriders = config.methodOverriders || [];
+      object.setMethodOverriders = function(values) {
+        var overriders = _.extend([], values);
+        if (config.isOverridenMethod('delete', overriders)) {
+          overriders.push('remove');
+        }
+        config.methodOverriders = overriders;
+        return this;
+      };
+
+      config.jsonp = _.isUndefined(config.jsonp) ? false : config.jsonp;
+      object.setJsonp = function(active) {
+        config.jsonp = active;
+      };
+
+      config.isOverridenMethod = function(method, values) {
+        var search = values || config.methodOverriders;
+        return !_.isUndefined(_.find(search, function(one) {
+          return one.toLowerCase() === method.toLowerCase();
+        }));
+      };
+
+      /**
+       * Sets the URL creator type. For now, only Path is created. In the future we'll have queryParams
+       **/
+      config.urlCreator = config.urlCreator || 'path';
+      object.setUrlCreator = function(name) {
+        if (!_.has(config.urlCreatorFactory, name)) {
+          throw new Error('URL Path selected isn\'t valid');
+        }
+
+        config.urlCreator = name;
+        return this;
+      };
+
+      /**
+       * You can set the restangular fields here. The 3 required fields for Restangular are:
+       *
+       * id: Id of the element
+       * route: name of the route of this element
+       * parentResource: the reference to the parent resource
+       *
+       *  All of this fields except for id, are handled (and created) by Restangular. By default,
+       *  the field values will be id, route and parentResource respectively
+       */
+      config.restangularFields = config.restangularFields || {
+        id: 'id',
+        route: 'route',
+        parentResource: 'parentResource',
+        restangularCollection: 'restangularCollection',
+        cannonicalId: '__cannonicalId',
+        etag: 'restangularEtag',
+        selfLink: 'href',
+        get: 'get',
+        getList: 'getList',
+        put: 'put',
+        post: 'post',
+        remove: 'remove',
+        head: 'head',
+        trace: 'trace',
+        options: 'options',
+        patch: 'patch',
+        getRestangularUrl: 'getRestangularUrl',
+        getRequestedUrl: 'getRequestedUrl',
+        putElement: 'putElement',
+        addRestangularMethod: 'addRestangularMethod',
+        getParentList: 'getParentList',
+        clone: 'clone',
+        ids: 'ids',
+        httpConfig: '_$httpConfig',
+        reqParams: 'reqParams',
+        one: 'one',
+        all: 'all',
+        several: 'several',
+        oneUrl: 'oneUrl',
+        allUrl: 'allUrl',
+        customPUT: 'customPUT',
+        customPATCH: 'customPATCH',
+        customPOST: 'customPOST',
+        customDELETE: 'customDELETE',
+        customGET: 'customGET',
+        customGETLIST: 'customGETLIST',
+        customOperation: 'customOperation',
+        doPUT: 'doPUT',
+        doPATCH: 'doPATCH',
+        doPOST: 'doPOST',
+        doDELETE: 'doDELETE',
+        doGET: 'doGET',
+        doGETLIST: 'doGETLIST',
+        fromServer: 'fromServer',
+        withConfig: 'withConfig',
+        withHttpConfig: 'withHttpConfig',
+        singleOne: 'singleOne',
+        plain: 'plain',
+        save: 'save',
+        restangularized: 'restangularized'
+      };
+      object.setRestangularFields = function(resFields) {
+        config.restangularFields =
+          _.extend(config.restangularFields, resFields);
+        return this;
+      };
+
+      config.isRestangularized = function(obj) {
+        return !!obj[config.restangularFields.restangularized];
+      };
+
+      config.setFieldToElem = function(field, elem, value) {
+        var properties = field.split('.');
+        var idValue = elem;
+        _.each(_.initial(properties), function(prop) {
+          idValue[prop] = {};
+          idValue = idValue[prop];
+        });
+        idValue[_.last(properties)] = value;
+        return this;
+      };
+
+      config.getFieldFromElem = function(field, elem) {
+        var properties = field.split('.');
+        var idValue = elem;
+        _.each(properties, function(prop) {
+          if (idValue) {
+            idValue = idValue[prop];
+          }
+        });
+        return angular.copy(idValue);
+      };
+
+      config.setIdToElem = function(elem, id /*, route */ ) {
+        config.setFieldToElem(config.restangularFields.id, elem, id);
+        return this;
+      };
+
+      config.getIdFromElem = function(elem) {
+        return config.getFieldFromElem(config.restangularFields.id, elem);
+      };
+
+      config.isValidId = function(elemId) {
+        return '' !== elemId && !_.isUndefined(elemId) && !_.isNull(elemId);
+      };
+
+      config.setUrlToElem = function(elem, url /*, route */ ) {
+        config.setFieldToElem(config.restangularFields.selfLink, elem, url);
+        return this;
+      };
+
+      config.getUrlFromElem = function(elem) {
+        return config.getFieldFromElem(config.restangularFields.selfLink, elem);
+      };
+
+      config.useCannonicalId = _.isUndefined(config.useCannonicalId) ? false : config.useCannonicalId;
+      object.setUseCannonicalId = function(value) {
+        config.useCannonicalId = value;
+        return this;
+      };
+
+      config.getCannonicalIdFromElem = function(elem) {
+        var cannonicalId = elem[config.restangularFields.cannonicalId];
+        var actualId = config.isValidId(cannonicalId) ? cannonicalId : config.getIdFromElem(elem);
+        return actualId;
+      };
+
+      /**
+       * Sets the Response parser. This is used in case your response isn't directly the data.
+       * For example if you have a response like {meta: {'meta'}, data: {name: 'Gonto'}}
+       * you can extract this data which is the one that needs wrapping
+       *
+       * The ResponseExtractor is a function that receives the response and the method executed.
+       */
+
+      config.responseInterceptors = config.responseInterceptors || [];
+
+      config.defaultResponseInterceptor = function(data /*, operation, what, url, response, deferred */ ) {
+        return data;
+      };
+
+      config.responseExtractor = function(data, operation, what, url, response, deferred) {
+        var interceptors = angular.copy(config.responseInterceptors);
+        interceptors.push(config.defaultResponseInterceptor);
+        var theData = data;
+        _.each(interceptors, function(interceptor) {
+          theData = interceptor(theData, operation,
+            what, url, response, deferred);
+        });
+        return theData;
+      };
+
+      object.addResponseInterceptor = function(extractor) {
+        config.responseInterceptors.push(extractor);
+        return this;
+      };
+
+      config.errorInterceptors = config.errorInterceptors || [];
+      object.addErrorInterceptor = function(interceptor) {
+        config.errorInterceptors.push(interceptor);
+        return this;
+      };
+
+      object.setResponseInterceptor = object.addResponseInterceptor;
+      object.setResponseExtractor = object.addResponseInterceptor;
+      object.setErrorInterceptor = object.addErrorInterceptor;
+
+      /**
+       * Response interceptor is called just before resolving promises.
+       */
+
+
+      /**
+       * Request interceptor is called before sending an object to the server.
+       */
+      config.requestInterceptors = config.requestInterceptors || [];
+
+      config.defaultInterceptor = function(element, operation, path, url, headers, params, httpConfig) {
+        return {
+          element: element,
+          headers: headers,
+          params: params,
+          httpConfig: httpConfig
+        };
+      };
+
+      config.fullRequestInterceptor = function(element, operation, path, url, headers, params, httpConfig) {
+        var interceptors = angular.copy(config.requestInterceptors);
+        var defaultRequest = config.defaultInterceptor(element, operation, path, url, headers, params, httpConfig);
+        return _.reduce(interceptors, function(request, interceptor) {
+          return _.extend(request, interceptor(request.element, operation,
+            path, url, request.headers, request.params, request.httpConfig));
+        }, defaultRequest);
+      };
+
+      object.addRequestInterceptor = function(interceptor) {
+        config.requestInterceptors.push(function(elem, operation, path, url, headers, params, httpConfig) {
+          return {
+            headers: headers,
+            params: params,
+            element: interceptor(elem, operation, path, url),
+            httpConfig: httpConfig
+          };
+        });
+        return this;
+      };
+
+      object.setRequestInterceptor = object.addRequestInterceptor;
+
+      object.addFullRequestInterceptor = function(interceptor) {
+        config.requestInterceptors.push(interceptor);
+        return this;
+      };
+
+      object.setFullRequestInterceptor = object.addFullRequestInterceptor;
+
+      config.onBeforeElemRestangularized = config.onBeforeElemRestangularized || function(elem) {
+        return elem;
+      };
+      object.setOnBeforeElemRestangularized = function(post) {
+        config.onBeforeElemRestangularized = post;
+        return this;
+      };
+
+      object.setRestangularizePromiseInterceptor = function(interceptor) {
+        config.restangularizePromiseInterceptor = interceptor;
+        return this;
+      };
+
+      /**
+       * This method is called after an element has been "Restangularized".
+       *
+       * It receives the element, a boolean indicating if it's an element or a collection
+       * and the name of the model
+       *
+       */
+      config.onElemRestangularized = config.onElemRestangularized || function(elem) {
+        return elem;
+      };
+      object.setOnElemRestangularized = function(post) {
+        config.onElemRestangularized = post;
+        return this;
+      };
+
+      config.shouldSaveParent = config.shouldSaveParent || function() {
+        return true;
+      };
+      object.setParentless = function(values) {
+        if (_.isArray(values)) {
+          config.shouldSaveParent = function(route) {
+            return !_.includes(values, route);
+          };
+        } else if (_.isBoolean(values)) {
+          config.shouldSaveParent = function() {
+            return !values;
+          };
+        }
+        return this;
+      };
+
+      /**
+       * This lets you set a suffix to every request.
+       *
+       * For example, if your api requires that for JSon requests you do /users/123.json, you can set that
+       * in here.
+       *
+       *
+       * By default, the suffix is null
+       */
+      config.suffix = _.isUndefined(config.suffix) ? null : config.suffix;
+      object.setRequestSuffix = function(newSuffix) {
+        config.suffix = newSuffix;
+        return this;
+      };
+
+      /**
+       * Add element transformers for certain routes.
+       */
+      config.transformers = config.transformers || {};
+      config.matchTransformers = config.matchTransformers || [];
+      object.addElementTransformer = function(type, secondArg, thirdArg) {
+        var isCollection = null;
+        var transformer = null;
+        if (arguments.length === 2) {
+          transformer = secondArg;
+        } else {
+          transformer = thirdArg;
+          isCollection = secondArg;
+        }
+
+        var transformerFn = function(coll, elem) {
+          if (_.isNull(isCollection) || (coll === isCollection)) {
+            return transformer(elem);
+          }
+          return elem;
+        };
+
+        if (_.isRegExp(type)) {
+          config.matchTransformers.push({
+            regexp: type,
+            transformer: transformerFn
+          });
+        } else {
+          if (!config.transformers[type]) {
+            config.transformers[type] = [];
+          }
+          config.transformers[type].push(transformerFn);
+        }
+
+        return object;
+      };
+
+      object.extendCollection = function(route, fn) {
+        return object.addElementTransformer(route, true, fn);
+      };
+
+      object.extendModel = function(route, fn) {
+        return object.addElementTransformer(route, false, fn);
+      };
+
+      config.transformElem = function(elem, isCollection, route, Restangular, force) {
+        if (!force && !config.transformLocalElements && !elem[config.restangularFields.fromServer]) {
+          return elem;
+        }
+
+        var changedElem = elem;
+
+        var matchTransformers = config.matchTransformers;
+        if (matchTransformers) {
+          _.each(matchTransformers, function(transformer) {
+            if (transformer.regexp.test(route)) {
+              changedElem = transformer.transformer(isCollection, changedElem);
+            }
+          });
+        }
+
+        var typeTransformers = config.transformers[route];
+        if (typeTransformers) {
+          _.each(typeTransformers, function(transformer) {
+            changedElem = transformer(isCollection, changedElem);
+          });
+        }
+        return config.onElemRestangularized(changedElem, isCollection, route, Restangular);
+      };
+
+      config.transformLocalElements = _.isUndefined(config.transformLocalElements) ?
+        false :
+        config.transformLocalElements;
+
+      object.setTransformOnlyServerElements = function(active) {
+        config.transformLocalElements = !active;
+      };
+
+      config.fullResponse = _.isUndefined(config.fullResponse) ? false : config.fullResponse;
+      object.setFullResponse = function(full) {
+        config.fullResponse = full;
+        return this;
+      };
+
+
+      //Internal values and functions
+      config.urlCreatorFactory = {};
+
+      /**
+       * Base URL Creator. Base prototype for everything related to it
+       **/
+
+      var BaseCreator = function() {};
+
+      BaseCreator.prototype.setConfig = function(config) {
+        this.config = config;
+        return this;
+      };
+
+      BaseCreator.prototype.parentsArray = function(current) {
+        var parents = [];
+        while (current) {
+          parents.push(current);
+          current = current[this.config.restangularFields.parentResource];
+        }
+        return parents.reverse();
+      };
+
+      function RestangularResource(config, $http, url, configurer) {
+        var resource = {};
+        _.each(_.keys(configurer), function(key) {
+          var value = configurer[key];
+
+          // Add default parameters
+          value.params = _.extend({}, value.params, config.defaultRequestParams[value.method.toLowerCase()]);
+          // We don't want the ? if no params are there
+          if (_.isEmpty(value.params)) {
+            delete value.params;
+          }
+
+          if (config.isSafe(value.method)) {
+
+            resource[key] = function() {
+              return $http(_.extend(value, {
+                url: url
+              }));
+            };
+
+          } else {
+
+            resource[key] = function(data) {
+              return $http(_.extend(value, {
+                url: url,
+                data: data
+              }));
+            };
+
+          }
+        });
+
+        return resource;
+      }
+
+      BaseCreator.prototype.resource = function(current, $http, localHttpConfig, callHeaders, callParams, what, etag, operation) {
+
+        var params = _.defaults(callParams || {}, this.config.defaultRequestParams.common);
+        var headers = _.defaults(callHeaders || {}, this.config.defaultHeaders);
+
+        if (etag) {
+          if (!config.isSafe(operation)) {
+            headers['If-Match'] = etag;
+          } else {
+            headers['If-None-Match'] = etag;
+          }
+        }
+
+        var url = this.base(current);
+
+        if (what || what === 0) {
+          var add = '';
+          if (!/\/$/.test(url)) {
+            add += '/';
+          }
+          add += what;
+          url += add;
+        }
+
+        if (this.config.suffix &&
+          url.indexOf(this.config.suffix, url.length - this.config.suffix.length) === -1 &&
+          !this.config.getUrlFromElem(current)) {
+          url += this.config.suffix;
+        }
+
+        current[this.config.restangularFields.httpConfig] = undefined;
+
+        return RestangularResource(this.config, $http, url, {
+          getList: this.config.withHttpValues(localHttpConfig, {
+            method: 'GET',
+            params: params,
+            headers: headers
+          }),
+
+          get: this.config.withHttpValues(localHttpConfig, {
+            method: 'GET',
+            params: params,
+            headers: headers
+          }),
+
+          jsonp: this.config.withHttpValues(localHttpConfig, {
+            method: 'jsonp',
+            params: params,
+            headers: headers
+          }),
+
+          put: this.config.withHttpValues(localHttpConfig, {
+            method: 'PUT',
+            params: params,
+            headers: headers
+          }),
+
+          post: this.config.withHttpValues(localHttpConfig, {
+            method: 'POST',
+            params: params,
+            headers: headers
+          }),
+
+          remove: this.config.withHttpValues(localHttpConfig, {
+            method: 'DELETE',
+            params: params,
+            headers: headers
+          }),
+
+          head: this.config.withHttpValues(localHttpConfig, {
+            method: 'HEAD',
+            params: params,
+            headers: headers
+          }),
+
+          trace: this.config.withHttpValues(localHttpConfig, {
+            method: 'TRACE',
+            params: params,
+            headers: headers
+          }),
+
+          options: this.config.withHttpValues(localHttpConfig, {
+            method: 'OPTIONS',
+            params: params,
+            headers: headers
+          }),
+
+          patch: this.config.withHttpValues(localHttpConfig, {
+            method: 'PATCH',
+            params: params,
+            headers: headers
+          })
+        });
+      };
+
+      /**
+       * This is the Path URL creator. It uses Path to show Hierarchy in the Rest API.
+       * This means that if you have an Account that then has a set of Buildings, a URL to a building
+       * would be /accounts/123/buildings/456
+       **/
+      var Path = function() {};
+
+      Path.prototype = new BaseCreator();
+
+      Path.prototype.normalizeUrl = function(url) {
+        var parts = /((?:http[s]?:)?\/\/)?(.*)?/.exec(url);
+        parts[2] = parts[2].replace(/[\\\/]+/g, '/');
+        return (typeof parts[1] !== 'undefined') ? parts[1] + parts[2] : parts[2];
+      };
+
+      Path.prototype.base = function(current) {
+        var __this = this;
+        return _.reduce(this.parentsArray(current), function(acum, elem) {
+          var elemUrl;
+          var elemSelfLink = __this.config.getUrlFromElem(elem);
+          if (elemSelfLink) {
+            if (__this.config.isAbsoluteUrl(elemSelfLink)) {
+              return elemSelfLink;
+            } else {
+              elemUrl = elemSelfLink;
+            }
+          } else {
+            elemUrl = elem[__this.config.restangularFields.route];
+
+            if (elem[__this.config.restangularFields.restangularCollection]) {
+              var ids = elem[__this.config.restangularFields.ids];
+              if (ids) {
+                elemUrl += '/' + ids.join(',');
+              }
+            } else {
+              var elemId;
+              if (__this.config.useCannonicalId) {
+                elemId = __this.config.getCannonicalIdFromElem(elem);
+              } else {
+                elemId = __this.config.getIdFromElem(elem);
+              }
+
+              if (config.isValidId(elemId) && !elem.singleOne) {
+                elemUrl += '/' + (__this.config.encodeIds ? encodeURIComponent(elemId) : elemId);
+              }
+            }
+          }
+          acum = acum.replace(/\/$/, '') + '/' + elemUrl;
+          return __this.normalizeUrl(acum);
+
+        }, this.config.baseUrl);
+      };
+
+
+
+      Path.prototype.fetchUrl = function(current, what) {
+        var baseUrl = this.base(current);
+        if (what) {
+          baseUrl += '/' + what;
+        }
+        return baseUrl;
+      };
+
+      Path.prototype.fetchRequestedUrl = function(current, what) {
+        var url = this.fetchUrl(current, what);
+        var params = current[config.restangularFields.reqParams];
+
+        // From here on and until the end of fetchRequestedUrl,
+        // the code has been kindly borrowed from angular.js
+        // The reason for such code bloating is coherence:
+        //   If the user were to use this for cache management, the
+        //   serialization of parameters would need to be identical
+        //   to the one done by angular for cache keys to match.
+        function sortedKeys(obj) {
+          var keys = [];
+          for (var key in obj) {
+            if (obj.hasOwnProperty(key)) {
+              keys.push(key);
+            }
+          }
+          return keys.sort();
+        }
+
+        function forEachSorted(obj, iterator, context) {
+          var keys = sortedKeys(obj);
+          for (var i = 0; i < keys.length; i++) {
+            iterator.call(context, obj[keys[i]], keys[i]);
+          }
+          return keys;
+        }
+
+        function encodeUriQuery(val, pctEncodeSpaces) {
+          return encodeURIComponent(val).
+          replace(/%40/gi, '@').
+          replace(/%3A/gi, ':').
+          replace(/%24/g, '$').
+          replace(/%2C/gi, ',').
+          replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
+        }
+
+        if (!params) {
+          return url + (this.config.suffix || '');
+        }
+
+        var parts = [];
+        forEachSorted(params, function(value, key) {
+          if (value === null || value === undefined) {
+            return;
+          }
+          if (!angular.isArray(value)) {
+            value = [value];
+          }
+
+          angular.forEach(value, function(v) {
+            if (angular.isObject(v)) {
+              v = angular.toJson(v);
+            }
+            parts.push(encodeUriQuery(key) + '=' + encodeUriQuery(v));
+          });
+        });
+
+        return url + (this.config.suffix || '') + ((url.indexOf('?') === -1) ? '?' : '&') + parts.join('&');
+      };
+
+      config.urlCreatorFactory.path = Path;
+    };
+
+    var globalConfiguration = {};
+
+    Configurer.init(this, globalConfiguration);
+
+
+
+    this.$get = ['$http', '$q', function($http, $q) {
+
+      function createServiceForConfiguration(config) {
+        var service = {};
+
+        var urlHandler = new config.urlCreatorFactory[config.urlCreator]();
+        urlHandler.setConfig(config);
+
+        function restangularizeBase(parent, elem, route, reqParams, fromServer) {
+          elem[config.restangularFields.route] = route;
+          elem[config.restangularFields.getRestangularUrl] = _.bind(urlHandler.fetchUrl, urlHandler, elem);
+          elem[config.restangularFields.getRequestedUrl] = _.bind(urlHandler.fetchRequestedUrl, urlHandler, elem);
+          elem[config.restangularFields.addRestangularMethod] = _.bind(addRestangularMethodFunction, elem);
+          elem[config.restangularFields.clone] = _.bind(copyRestangularizedElement, elem, elem);
+          elem[config.restangularFields.reqParams] = _.isEmpty(reqParams) ? null : reqParams;
+          elem[config.restangularFields.withHttpConfig] = _.bind(withHttpConfig, elem);
+          elem[config.restangularFields.plain] = _.bind(stripRestangular, elem, elem);
+
+          // Tag element as restangularized
+          elem[config.restangularFields.restangularized] = true;
+
+          // RequestLess connection
+          elem[config.restangularFields.one] = _.bind(one, elem, elem);
+          elem[config.restangularFields.all] = _.bind(all, elem, elem);
+          elem[config.restangularFields.several] = _.bind(several, elem, elem);
+          elem[config.restangularFields.oneUrl] = _.bind(oneUrl, elem, elem);
+          elem[config.restangularFields.allUrl] = _.bind(allUrl, elem, elem);
+
+          elem[config.restangularFields.fromServer] = !!fromServer;
+
+          if (parent && config.shouldSaveParent(route)) {
+            var parentId = config.getIdFromElem(parent);
+            var parentUrl = config.getUrlFromElem(parent);
+
+            var restangularFieldsForParent = _.union(
+              _.values(_.pick(config.restangularFields, ['route', 'singleOne', 'parentResource'])),
+              config.extraFields
+            );
+            var parentResource = _.pick(parent, restangularFieldsForParent);
+
+            if (config.isValidId(parentId)) {
+              config.setIdToElem(parentResource, parentId, route);
+            }
+            if (config.isValidId(parentUrl)) {
+              config.setUrlToElem(parentResource, parentUrl, route);
+            }
+
+            elem[config.restangularFields.parentResource] = parentResource;
+          } else {
+            elem[config.restangularFields.parentResource] = null;
+          }
+          return elem;
+        }
+
+        function one(parent, route, id, singleOne) {
+          var error;
+          if (_.isNumber(route) || _.isNumber(parent)) {
+            error = 'You\'re creating a Restangular entity with the number ';
+            error += 'instead of the route or the parent. For example, you can\'t call .one(12).';
+            throw new Error(error);
+          }
+          if (_.isUndefined(route)) {
+            error = 'You\'re creating a Restangular entity either without the path. ';
+            error += 'For example you can\'t call .one(). Please check if your arguments are valid.';
+            throw new Error(error);
+          }
+          var elem = {};
+          config.setIdToElem(elem, id, route);
+          config.setFieldToElem(config.restangularFields.singleOne, elem, singleOne);
+          return restangularizeElem(parent, elem, route, false);
+        }
+
+
+        function all(parent, route) {
+          return restangularizeCollection(parent, [], route, false);
+        }
+
+        function several(parent, route /*, ids */ ) {
+          var collection = [];
+          collection[config.restangularFields.ids] = Array.prototype.splice.call(arguments, 2);
+          return restangularizeCollection(parent, collection, route, false);
+        }
+
+        function oneUrl(parent, route, url) {
+          if (!route) {
+            throw new Error('Route is mandatory when creating new Restangular objects.');
+          }
+          var elem = {};
+          config.setUrlToElem(elem, url, route);
+          return restangularizeElem(parent, elem, route, false);
+        }
+
+
+        function allUrl(parent, route, url) {
+          if (!route) {
+            throw new Error('Route is mandatory when creating new Restangular objects.');
+          }
+          var elem = {};
+          config.setUrlToElem(elem, url, route);
+          return restangularizeCollection(parent, elem, route, false);
+        }
+        // Promises
+        function restangularizePromise(promise, isCollection, valueToFill) {
+          promise.call = _.bind(promiseCall, promise);
+          promise.get = _.bind(promiseGet, promise);
+          promise[config.restangularFields.restangularCollection] = isCollection;
+          if (isCollection) {
+            promise.push = _.bind(promiseCall, promise, 'push');
+          }
+          promise.$object = valueToFill;
+          if (config.restangularizePromiseInterceptor) {
+            config.restangularizePromiseInterceptor(promise);
+          }
+          return promise;
+        }
+
+        function promiseCall(method) {
+          var deferred = $q.defer();
+          var callArgs = arguments;
+          var filledValue = {};
+          this.then(function(val) {
+            var params = Array.prototype.slice.call(callArgs, 1);
+            var func = val[method];
+            func.apply(val, params);
+            filledValue = val;
+            deferred.resolve(val);
+          });
+          return restangularizePromise(deferred.promise, this[config.restangularFields.restangularCollection], filledValue);
+        }
+
+        function promiseGet(what) {
+          var deferred = $q.defer();
+          var filledValue = {};
+          this.then(function(val) {
+            filledValue = val[what];
+            deferred.resolve(filledValue);
+          });
+          return restangularizePromise(deferred.promise, this[config.restangularFields.restangularCollection], filledValue);
+        }
+
+        function resolvePromise(deferred, response, data, filledValue) {
+          _.extend(filledValue, data);
+
+          // Trigger the full response interceptor.
+          if (config.fullResponse) {
+            return deferred.resolve(_.extend(response, {
+              data: data
+            }));
+          } else {
+            deferred.resolve(data);
+          }
+        }
+
+
+        // Elements
+        function stripRestangular(elem) {
+          if (_.isArray(elem)) {
+            var array = [];
+            _.each(elem, function(value) {
+              array.push(config.isRestangularized(value) ? stripRestangular(value) : value);
+            });
+            return array;
+          } else {
+            return _.omit(elem, _.values(_.omit(config.restangularFields, 'id')));
+          }
+        }
+
+        function addCustomOperation(elem) {
+          elem[config.restangularFields.customOperation] = _.bind(customFunction, elem);
+          var requestMethods = {
+            get: customFunction,
+            delete: customFunction
+          };
+          _.each(['put', 'patch', 'post'], function(name) {
+            requestMethods[name] = function(operation, elem, path, params, headers) {
+              return _.bind(customFunction, this)(operation, path, params, headers, elem);
+            };
+          });
+          _.each(requestMethods, function(requestFunc, name) {
+            var callOperation = name === 'delete' ? 'remove' : name;
+            _.each(['do', 'custom'], function(alias) {
+              elem[alias + name.toUpperCase()] = _.bind(requestFunc, elem, callOperation);
+            });
+          });
+          elem[config.restangularFields.customGETLIST] = _.bind(fetchFunction, elem);
+          elem[config.restangularFields.doGETLIST] = elem[config.restangularFields.customGETLIST];
+        }
+
+        function copyRestangularizedElement(element) {
+          var copiedElement = angular.copy(element);
+
+          // check if we're dealing with a collection (i.e. an array)
+          // and restangularize the element using the proper restangularizer,
+          // element / collection
+          if (_.isArray(element)) {
+            return restangularizeCollection(
+              element[config.restangularFields.parentResource],
+              copiedElement,
+              element[config.restangularFields.route],
+              element[config.restangularFields.fromServer],
+              element[config.restangularFields.reqParams]
+            );
+          }
+
+          // not a collection, restangularize it as an element
+          return restangularizeElem(
+            element[config.restangularFields.parentResource],
+            copiedElement,
+            element[config.restangularFields.route],
+            element[config.restangularFields.fromServer],
+            element[config.restangularFields.restangularCollection],
+            element[config.restangularFields.reqParams]
+          );
+        }
+
+        function restangularizeElem(parent, element, route, fromServer, collection, reqParams) {
+          var elem = config.onBeforeElemRestangularized(element, false, route);
+
+          var localElem = restangularizeBase(parent, elem, route, reqParams, fromServer);
+
+          if (config.useCannonicalId) {
+            localElem[config.restangularFields.cannonicalId] = config.getIdFromElem(localElem);
+          }
+
+          if (collection) {
+            localElem[config.restangularFields.getParentList] = function() {
+              return collection;
+            };
+          }
+
+          localElem[config.restangularFields.restangularCollection] = false;
+          localElem[config.restangularFields.get] = _.bind(getFunction, localElem);
+          localElem[config.restangularFields.getList] = _.bind(fetchFunction, localElem);
+          localElem[config.restangularFields.put] = _.bind(putFunction, localElem);
+          localElem[config.restangularFields.post] = _.bind(postFunction, localElem);
+          localElem[config.restangularFields.remove] = _.bind(deleteFunction, localElem);
+          localElem[config.restangularFields.head] = _.bind(headFunction, localElem);
+          localElem[config.restangularFields.trace] = _.bind(traceFunction, localElem);
+          localElem[config.restangularFields.options] = _.bind(optionsFunction, localElem);
+          localElem[config.restangularFields.patch] = _.bind(patchFunction, localElem);
+          localElem[config.restangularFields.save] = _.bind(save, localElem);
+
+          addCustomOperation(localElem);
+          return config.transformElem(localElem, false, route, service, true);
+        }
+
+        function restangularizeCollection(parent, element, route, fromServer, reqParams) {
+          var elem = config.onBeforeElemRestangularized(element, true, route);
+
+          var localElem = restangularizeBase(parent, elem, route, reqParams, fromServer);
+          localElem[config.restangularFields.restangularCollection] = true;
+          localElem[config.restangularFields.post] = _.bind(postFunction, localElem, null);
+          localElem[config.restangularFields.remove] = _.bind(deleteFunction, localElem);
+          localElem[config.restangularFields.head] = _.bind(headFunction, localElem);
+          localElem[config.restangularFields.trace] = _.bind(traceFunction, localElem);
+          localElem[config.restangularFields.putElement] = _.bind(putElementFunction, localElem);
+          localElem[config.restangularFields.options] = _.bind(optionsFunction, localElem);
+          localElem[config.restangularFields.patch] = _.bind(patchFunction, localElem);
+          localElem[config.restangularFields.get] = _.bind(getById, localElem);
+          localElem[config.restangularFields.getList] = _.bind(fetchFunction, localElem, null);
+
+          addCustomOperation(localElem);
+          return config.transformElem(localElem, true, route, service, true);
+        }
+
+        function restangularizeCollectionAndElements(parent, element, route, fromServer) {
+          var collection = restangularizeCollection(parent, element, route, fromServer);
+          _.each(collection, function(elem) {
+            if (elem) {
+              restangularizeElem(parent, elem, route, fromServer);
+            }
+          });
+          return collection;
+        }
+
+        function getById(id, reqParams, headers) {
+          return this.customGET(id.toString(), reqParams, headers);
+        }
+
+        function putElementFunction(idx, params, headers) {
+          var __this = this;
+          var elemToPut = this[idx];
+          var deferred = $q.defer();
+          var filledArray = [];
+          filledArray = config.transformElem(filledArray, true, elemToPut[config.restangularFields.route], service);
+          elemToPut.put(params, headers).then(function(serverElem) {
+            var newArray = copyRestangularizedElement(__this);
+            newArray[idx] = serverElem;
+            filledArray = newArray;
+            deferred.resolve(newArray);
+          }, function(response) {
+            deferred.reject(response);
+          });
+
+          return restangularizePromise(deferred.promise, true, filledArray);
+        }
+
+        function parseResponse(resData, operation, route, fetchUrl, response, deferred) {
+          var data = config.responseExtractor(resData, operation, route, fetchUrl, response, deferred);
+          var etag = response.headers('ETag');
+          if (data && etag) {
+            data[config.restangularFields.etag] = etag;
+          }
+          return data;
+        }
+
+
+        function fetchFunction(what, reqParams, headers) {
+          var __this = this;
+          var deferred = $q.defer();
+          var operation = 'getList';
+          var url = urlHandler.fetchUrl(this, what);
+          var whatFetched = what || __this[config.restangularFields.route];
+
+          var request = config.fullRequestInterceptor(null, operation,
+            whatFetched, url, headers || {}, reqParams || {}, this[config.restangularFields.httpConfig] || {});
+
+          var filledArray = [];
+          filledArray = config.transformElem(filledArray, true, whatFetched, service);
+
+          var method = 'getList';
+
+          if (config.jsonp) {
+            method = 'jsonp';
+          }
+
+          var okCallback = function(response) {
+            var resData = response.data;
+            var fullParams = response.config.params;
+            var data = parseResponse(resData, operation, whatFetched, url, response, deferred);
+
+            // support empty response for getList() calls (some APIs respond with 204 and empty body)
+            if (_.isUndefined(data) || '' === data) {
+              data = [];
+            }
+            if (!_.isArray(data)) {
+              throw new Error('Response for getList SHOULD be an array and not an object or something else');
+            }
+
+            if (true === config.plainByDefault) {
+              return resolvePromise(deferred, response, data, filledArray);
+            }
+
+            var processedData = _.map(data, function(elem) {
+              if (!__this[config.restangularFields.restangularCollection]) {
+                return restangularizeElem(__this, elem, what, true, data);
+              } else {
+                return restangularizeElem(__this[config.restangularFields.parentResource],
+                  elem, __this[config.restangularFields.route], true, data);
+              }
+            });
+
+            processedData = _.extend(data, processedData);
+
+            if (!__this[config.restangularFields.restangularCollection]) {
+              resolvePromise(
+                deferred,
+                response,
+                restangularizeCollection(
+                  __this,
+                  processedData,
+                  what,
+                  true,
+                  fullParams
+                ),
+                filledArray
+              );
+            } else {
+              resolvePromise(
+                deferred,
+                response,
+                restangularizeCollection(
+                  __this[config.restangularFields.parentResource],
+                  processedData,
+                  __this[config.restangularFields.route],
+                  true,
+                  fullParams
+                ),
+                filledArray
+              );
+            }
+          };
+
+          urlHandler.resource(this, $http, request.httpConfig, request.headers, request.params, what,
+            this[config.restangularFields.etag], operation)[method]().then(okCallback, function error(response) {
+            if (response.status === 304 && __this[config.restangularFields.restangularCollection]) {
+              resolvePromise(deferred, response, __this, filledArray);
+            } else if (_.every(config.errorInterceptors, function(cb) {
+                return cb(response, deferred, okCallback) !== false;
+              })) {
+              // triggered if no callback returns false
+              deferred.reject(response);
+            }
+          });
+
+          return restangularizePromise(deferred.promise, true, filledArray);
+        }
+
+        function withHttpConfig(httpConfig) {
+          this[config.restangularFields.httpConfig] = httpConfig;
+          return this;
+        }
+
+        function save(params, headers) {
+          if (this[config.restangularFields.fromServer]) {
+            return this[config.restangularFields.put](params, headers);
+          } else {
+            return _.bind(elemFunction, this)('post', undefined, params, undefined, headers);
+          }
+        }
+
+        function elemFunction(operation, what, params, obj, headers) {
+          var __this = this;
+          var deferred = $q.defer();
+          var resParams = params || {};
+          var route = what || this[config.restangularFields.route];
+          var fetchUrl = urlHandler.fetchUrl(this, what);
+
+          var callObj = obj || this;
+          // fallback to etag on restangular object (since for custom methods we probably don't explicitly specify the etag field)
+          var etag = callObj[config.restangularFields.etag] || (operation !== 'post' ? this[config.restangularFields.etag] : null);
+
+          if (_.isObject(callObj) && config.isRestangularized(callObj)) {
+            callObj = stripRestangular(callObj);
+          }
+          var request = config.fullRequestInterceptor(callObj, operation, route, fetchUrl,
+            headers || {}, resParams || {}, this[config.restangularFields.httpConfig] || {});
+
+          var filledObject = {};
+          filledObject = config.transformElem(filledObject, false, route, service);
+
+          var okCallback = function(response) {
+            var resData = response.data;
+            var fullParams = response.config.params;
+            var elem = parseResponse(resData, operation, route, fetchUrl, response, deferred);
+
+            // accept 0 as response
+            if (elem !== null && elem !== undefined && elem !== '') {
+              var data;
+
+              if (true === config.plainByDefault) {
+                return resolvePromise(deferred, response, elem, filledObject);
+              }
+
+              if (operation === 'post' && !__this[config.restangularFields.restangularCollection]) {
+                data = restangularizeElem(
+                  __this[config.restangularFields.parentResource],
+                  elem,
+                  route,
+                  true,
+                  null,
+                  fullParams
+                );
+                resolvePromise(deferred, response, data, filledObject);
+              } else {
+                data = restangularizeElem(
+                  __this[config.restangularFields.parentResource],
+                  elem,
+                  __this[config.restangularFields.route],
+                  true,
+                  null,
+                  fullParams
+                );
+
+                data[config.restangularFields.singleOne] = __this[config.restangularFields.singleOne];
+                resolvePromise(deferred, response, data, filledObject);
+              }
+
+            } else {
+              resolvePromise(deferred, response, undefined, filledObject);
+            }
+          };
+
+          var errorCallback = function(response) {
+            if (response.status === 304 && config.isSafe(operation)) {
+              resolvePromise(deferred, response, __this, filledObject);
+            } else if (_.every(config.errorInterceptors, function(cb) {
+                return cb(response, deferred, okCallback) !== false;
+              })) {
+              // triggered if no callback returns false
+              deferred.reject(response);
+            }
+          };
+          // Overriding HTTP Method
+          var callOperation = operation;
+          var callHeaders = _.extend({}, request.headers);
+          var isOverrideOperation = config.isOverridenMethod(operation);
+          if (isOverrideOperation) {
+            callOperation = 'post';
+            callHeaders = _.extend(callHeaders, {
+              'X-HTTP-Method-Override': operation === 'remove' ? 'DELETE' : operation.toUpperCase()
+            });
+          } else if (config.jsonp && callOperation === 'get') {
+            callOperation = 'jsonp';
+          }
+
+          if (config.isSafe(operation)) {
+            if (isOverrideOperation) {
+              urlHandler.resource(this, $http, request.httpConfig, callHeaders, request.params,
+                what, etag, callOperation)[callOperation]({}).then(okCallback, errorCallback);
+            } else {
+              urlHandler.resource(this, $http, request.httpConfig, callHeaders, request.params,
+                what, etag, callOperation)[callOperation]().then(okCallback, errorCallback);
+            }
+          } else {
+            urlHandler.resource(this, $http, request.httpConfig, callHeaders, request.params,
+              what, etag, callOperation)[callOperation](request.element).then(okCallback, errorCallback);
+          }
+
+          return restangularizePromise(deferred.promise, false, filledObject);
+        }
+
+        function getFunction(params, headers) {
+          return _.bind(elemFunction, this)('get', undefined, params, undefined, headers);
+        }
+
+        function deleteFunction(params, headers) {
+          return _.bind(elemFunction, this)('remove', undefined, params, undefined, headers);
+        }
+
+        function putFunction(params, headers) {
+          return _.bind(elemFunction, this)('put', undefined, params, undefined, headers);
+        }
+
+        function postFunction(what, elem, params, headers) {
+          return _.bind(elemFunction, this)('post', what, params, elem, headers);
+        }
+
+        function headFunction(params, headers) {
+          return _.bind(elemFunction, this)('head', undefined, params, undefined, headers);
+        }
+
+        function traceFunction(params, headers) {
+          return _.bind(elemFunction, this)('trace', undefined, params, undefined, headers);
+        }
+
+        function optionsFunction(params, headers) {
+          return _.bind(elemFunction, this)('options', undefined, params, undefined, headers);
+        }
+
+        function patchFunction(elem, params, headers) {
+          return _.bind(elemFunction, this)('patch', undefined, params, elem, headers);
+        }
+
+        function customFunction(operation, path, params, headers, elem) {
+          return _.bind(elemFunction, this)(operation, path, params, elem, headers);
+        }
+
+        function addRestangularMethodFunction(name, operation, path, defaultParams, defaultHeaders, defaultElem) {
+          var bindedFunction;
+          if (operation === 'getList') {
+            bindedFunction = _.bind(fetchFunction, this, path);
+          } else {
+            bindedFunction = _.bind(customFunction, this, operation, path);
+          }
+
+          var createdFunction = function(params, headers, elem) {
+            var callParams = _.defaults({
+              params: params,
+              headers: headers,
+              elem: elem
+            }, {
+              params: defaultParams,
+              headers: defaultHeaders,
+              elem: defaultElem
+            });
+            return bindedFunction(callParams.params, callParams.headers, callParams.elem);
+          };
+
+          if (config.isSafe(operation)) {
+            this[name] = createdFunction;
+          } else {
+            this[name] = function(elem, params, headers) {
+              return createdFunction(params, headers, elem);
+            };
+          }
+        }
+
+        function withConfigurationFunction(configurer) {
+          var newConfig = angular.copy(_.omit(config, 'configuration'));
+          Configurer.init(newConfig, newConfig);
+          configurer(newConfig);
+          return createServiceForConfiguration(newConfig);
+        }
+
+        function toService(route, parent) {
+          var knownCollectionMethods = _.values(config.restangularFields);
+          var serv = {};
+          var collection = (parent || service).all(route);
+          serv.one = _.bind(one, (parent || service), parent, route);
+          serv.post = _.bind(collection.post, collection);
+          serv.getList = _.bind(collection.getList, collection);
+          serv.withHttpConfig = _.bind(collection.withHttpConfig, collection);
+          serv.get = _.bind(collection.get, collection);
+
+          for (var prop in collection) {
+            if (collection.hasOwnProperty(prop) && _.isFunction(collection[prop]) && !_.includes(knownCollectionMethods, prop)) {
+              serv[prop] = _.bind(collection[prop], collection);
+            }
+          }
+
+          return serv;
+        }
+
+
+        Configurer.init(service, config);
+
+        service.copy = _.bind(copyRestangularizedElement, service);
+
+        service.service = _.bind(toService, service);
+
+        service.withConfig = _.bind(withConfigurationFunction, service);
+
+        service.one = _.bind(one, service, null);
+
+        service.all = _.bind(all, service, null);
+
+        service.several = _.bind(several, service, null);
+
+        service.oneUrl = _.bind(oneUrl, service, null);
+
+        service.allUrl = _.bind(allUrl, service, null);
+
+        service.stripRestangular = _.bind(stripRestangular, service);
+
+        service.restangularizeElement = _.bind(restangularizeElem, service);
+
+        service.restangularizeCollection = _.bind(restangularizeCollectionAndElements, service);
+
+        return service;
+      }
+
+      return createServiceForConfiguration(globalConfiguration);
+    }];
+  });
+  return restangular.name;
+}));
