diff --git a/src/main/webapp/index.html b/src/main/webapp/index.html
index cdb404def..abc97256f 100644
--- a/src/main/webapp/index.html
+++ b/src/main/webapp/index.html
@@ -33,6 +33,7 @@
+
diff --git a/src/main/webapp/js/app.js b/src/main/webapp/js/app.js
index a2acfdf82..e825a99c2 100644
--- a/src/main/webapp/js/app.js
+++ b/src/main/webapp/js/app.js
@@ -1,4 +1,4 @@
-var app = angular.module('spring-petclinic', ['ui.router','ui.router.stateHelper','ngAnimate','ngCookies','ngResource','ngMockE2E']);
+var app = angular.module('spring-petclinic', ['ui.router','ui.router.stateHelper','ngAnimate','ngCookies','ngResource','ngMockE2E','ngStorage']);
/** Start of Configurable constants **/
diff --git a/src/main/webapp/js/lib/angular-storage.js b/src/main/webapp/js/lib/angular-storage.js
new file mode 100644
index 000000000..0d71a2d91
--- /dev/null
+++ b/src/main/webapp/js/lib/angular-storage.js
@@ -0,0 +1,105 @@
+'use strict';
+
+(function() {
+
+ /**
+ * @ngdoc overview
+ * @name ngStorage
+ */
+
+ angular.module('ngStorage', []).
+
+ /**
+ * @ngdoc object
+ * @name ngStorage.$localStorage
+ * @requires $rootScope
+ * @requires $window
+ */
+
+ factory('$localStorage', _storageFactory('localStorage')).
+
+ /**
+ * @ngdoc object
+ * @name ngStorage.$sessionStorage
+ * @requires $rootScope
+ * @requires $window
+ */
+
+ factory('$sessionStorage', _storageFactory('sessionStorage'));
+
+ function _storageFactory(storageType) {
+ return [
+ '$rootScope',
+ '$window',
+ '$log',
+
+ function(
+ $rootScope,
+ $window,
+ $log
+ ){
+ // #9: Assign a placeholder object if Web Storage is unavailable to prevent breaking the entire AngularJS app
+ var webStorage = $window[storageType] || ($log.warn('This browser does not support Web Storage!'), {}),
+ $storage = {
+ $default: function(items) {
+ for (var k in items) {
+ angular.isDefined($storage[k]) || ($storage[k] = items[k]);
+ }
+
+ return $storage;
+ },
+ $reset: function(items) {
+ for (var k in $storage) {
+ '$' === k[0] || delete $storage[k];
+ }
+
+ return $storage.$default(items);
+ }
+ },
+ _last$storage,
+ _debounce;
+
+ for (var i = 0, k; i < webStorage.length; i++) {
+ // #8, #10: `webStorage.key(i)` may be an empty string (or throw an exception in IE9 if `webStorage` is empty)
+ (k = webStorage.key(i)) && 'ngStorage-' === k.slice(0, 10) && ($storage[k.slice(10)] = angular.fromJson(webStorage.getItem(k)));
+ }
+
+ _last$storage = angular.copy($storage);
+
+ $rootScope.$watch(function() {
+ _debounce || (_debounce = setTimeout(function() {
+ _debounce = null;
+
+ if (!angular.equals($storage, _last$storage)) {
+ angular.forEach($storage, function(v, k) {
+ angular.isDefined(v) && '$' !== k[0] && webStorage.setItem('ngStorage-' + k, angular.toJson(v));
+
+ delete _last$storage[k];
+ });
+
+ for (var k in _last$storage) {
+ webStorage.removeItem('ngStorage-' + k);
+ }
+
+ _last$storage = angular.copy($storage);
+ }
+ }, 100));
+ });
+
+ // #6: Use `$window.addEventListener` instead of `angular.element` to avoid the jQuery-specific `event.originalEvent`
+ 'localStorage' === storageType && $window.addEventListener && $window.addEventListener('storage', function(event) {
+ if ('ngStorage-' === event.key.slice(0, 10)) {
+ event.newValue ? $storage[event.key.slice(10)] = angular.fromJson(event.newValue) : delete $storage[event.key.slice(10)];
+
+ _last$storage = angular.copy($storage);
+
+ $rootScope.$apply();
+ }
+ });
+
+ return $storage;
+ }
+ ];
+ }
+
+})();