diff --git a/app/common/directives/dirPagination.js b/app/common/directives/dirPagination.js
new file mode 100644
index 0000000..97f7a1f
--- /dev/null
+++ b/app/common/directives/dirPagination.js
@@ -0,0 +1,699 @@
+/**
+ * dirPagination - AngularJS module for paginating (almost) anything.
+ * https://github.com/michaelbromley/angularUtils
+ *
+ *
+ * Credits
+ * =======
+ *
+ * Daniel Tabuenca:
+ * https://groups.google.com/d/msg/angular/an9QpzqIYiM/r8v-3W1X5vcJ for the idea
+ * on how to dynamically invoke the ng-repeat directive.
+ *
+ * I borrowed a couple of lines and a few attribute names from the AngularUI
+ * Bootstrap project:
+ * https://github.com/angular-ui/bootstrap/blob/master/src/pagination/pagination.js
+ *
+ * Copyright 2014 Michael Bromley <michael@michaelbromley.co.uk>
+ */
+
+(function() {
+
+/**
+ * Config
+ */
+var moduleName = 'app.common.directives.dirPagination';
+var DEFAULT_ID = '__default';
+
+/**
+ * Module
+ */
+angular.module(moduleName, [])
+    .directive(
+        'dirPaginate',
+        ['$compile', '$parse', 'paginationService', dirPaginateDirective])
+    .directive('dirPaginateNoCompile', noCompileDirective)
+    .directive(
+        'dirPaginationControls',
+        [
+          'paginationService', 'paginationTemplate',
+          dirPaginationControlsDirective
+        ])
+    .filter('itemsPerPage', ['paginationService', itemsPerPageFilter])
+    .service('paginationService', paginationService)
+    .provider('paginationTemplate', paginationTemplateProvider)
+    .run(['$templateCache', dirPaginationControlsTemplateInstaller]);
+
+function dirPaginateDirective($compile, $parse, paginationService) {
+  return {
+    terminal: true,
+    multiElement: true,
+    priority: 100,
+    compile: dirPaginationCompileFn
+  };
+
+  function dirPaginationCompileFn(tElement, tAttrs) {
+    var expression = tAttrs.dirPaginate;
+    // regex taken directly from
+    // https://github.com/angular/angular.js/blob/v1.4.x/src/ng/directive/ngRepeat.js#L339
+    var match = expression.match(
+        /^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+track\s+by\s+([\s\S]+?))?\s*$/);
+
+    var filterPattern =
+        /\|\s*itemsPerPage\s*:\s*(.*\(\s*\w*\)|([^\)]*?(?=\s+as\s+))|[^\)]*)/;
+    if (match[2].match(filterPattern) === null) {
+      throw 'pagination directive: the \'itemsPerPage\' filter must be set.';
+    }
+    var itemsPerPageFilterRemoved = match[2].replace(filterPattern, '');
+    var collectionGetter = $parse(itemsPerPageFilterRemoved);
+
+    addNoCompileAttributes(tElement);
+
+    // If any value is specified for paginationId, we register the un-evaluated
+    // expression at this stage for the benefit of any dir-pagination-controls
+    // directives that may be looking for this ID.
+    var rawId = tAttrs.paginationId || DEFAULT_ID;
+    paginationService.registerInstance(rawId);
+
+    return function dirPaginationLinkFn(scope, element, attrs) {
+      // Now that we have access to the `scope` we can interpolate any
+      // expression given in the paginationId attribute and potentially register
+      // a new ID if it evaluates to a different value than the rawId.
+      var paginationId =
+          $parse(attrs.paginationId)(scope) || attrs.paginationId || DEFAULT_ID;
+
+      // (TODO: this seems sound, but I'm reverting as many bug reports followed
+      // it's introduction in 0.11.0. Needs more investigation.) In case rawId
+      // != paginationId we deregister using rawId for the sake of general
+      // cleanliness before registering using paginationId
+      // paginationService.deregisterInstance(rawId);
+      paginationService.registerInstance(paginationId);
+
+      var repeatExpression = getRepeatExpression(expression, paginationId);
+      addNgRepeatToElement(element, attrs, repeatExpression);
+
+      removeTemporaryAttributes(element);
+      var compiled = $compile(element);
+
+      var currentPageGetter =
+          makeCurrentPageGetterFn(scope, attrs, paginationId);
+      paginationService.setCurrentPageParser(
+          paginationId, currentPageGetter, scope);
+
+      if (typeof attrs.totalItems !== 'undefined') {
+        paginationService.setAsyncModeTrue(paginationId);
+        scope.$watch(
+            function() {
+              return $parse(attrs.totalItems)(scope);
+            },
+            function(result) {
+              if (0 <= result) {
+                paginationService.setCollectionLength(paginationId, result);
+              }
+            });
+      } else {
+        paginationService.setAsyncModeFalse(paginationId);
+        scope.$watchCollection(
+            function() {
+              return collectionGetter(scope);
+            },
+            function(collection) {
+              if (collection) {
+                var collectionLength = (collection instanceof Array) ?
+                    collection.length :
+                    Object.keys(collection).length;
+                paginationService.setCollectionLength(
+                    paginationId, collectionLength);
+              }
+            });
+      }
+
+      // Delegate to the link function returned by the new compilation of the
+      // ng-repeat
+      compiled(scope);
+
+      // (TODO: Reverting this due to many bug reports in v 0.11.0. Needs
+      // investigation as the principle is sound) When the scope is destroyed,
+      // we make sure to remove the reference to it in paginationService so that
+      // it can be properly garbage collected scope.$on('$destroy', function
+      // destroyDirPagination() {
+      //     paginationService.deregisterInstance(paginationId);
+      // });
+    };
+  }
+
+  /**
+   * If a pagination id has been specified, we need to check that it is present
+   * as the second argument passed to the itemsPerPage filter. If it is not
+   * there, we add it and return the modified expression.
+   *
+   * @param expression
+   * @param paginationId
+   * @returns {*}
+   */
+  function getRepeatExpression(expression, paginationId) {
+    var repeatExpression,
+        idDefinedInFilter =
+            !!expression.match(/(\|\s*itemsPerPage\s*:[^|]*:[^|]*)/);
+
+    if (paginationId !== DEFAULT_ID && !idDefinedInFilter) {
+      repeatExpression = expression.replace(
+          /(\|\s*itemsPerPage\s*:\s*[^|\s]*)/, '$1 : \'' + paginationId + '\'');
+    } else {
+      repeatExpression = expression;
+    }
+
+    return repeatExpression;
+  }
+
+  /**
+   * Adds the ng-repeat directive to the element. In the case of multi-element
+   * (-start, -end) it adds the appropriate multi-element ng-repeat to the first
+   * and last element in the range.
+   * @param element
+   * @param attrs
+   * @param repeatExpression
+   */
+  function addNgRepeatToElement(element, attrs, repeatExpression) {
+    if (element[0].hasAttribute('dir-paginate-start') ||
+        element[0].hasAttribute('data-dir-paginate-start')) {
+      // using multiElement mode (dir-paginate-start, dir-paginate-end)
+      attrs.$set('ngRepeatStart', repeatExpression);
+      element.eq(element.length - 1).attr('ng-repeat-end', true);
+    } else {
+      attrs.$set('ngRepeat', repeatExpression);
+    }
+  }
+
+  /**
+   * Adds the dir-paginate-no-compile directive to each element in the tElement
+   * range.
+   * @param tElement
+   */
+  function addNoCompileAttributes(tElement) {
+    angular.forEach(tElement, function(el) {
+      if (el.nodeType === 1) {
+        angular.element(el).attr('dir-paginate-no-compile', true);
+      }
+    });
+  }
+
+  /**
+   * Removes the variations on dir-paginate (data-, -start, -end) and the
+   * dir-paginate-no-compile directives.
+   * @param element
+   */
+  function removeTemporaryAttributes(element) {
+    angular.forEach(element, function(el) {
+      if (el.nodeType === 1) {
+        angular.element(el).removeAttr('dir-paginate-no-compile');
+      }
+    });
+    element.eq(0)
+        .removeAttr('dir-paginate-start')
+        .removeAttr('dir-paginate')
+        .removeAttr('data-dir-paginate-start')
+        .removeAttr('data-dir-paginate');
+    element.eq(element.length - 1)
+        .removeAttr('dir-paginate-end')
+        .removeAttr('data-dir-paginate-end');
+  }
+
+  /**
+   * Creates a getter function for the current-page attribute, using the
+   * expression provided or a default value if no current-page expression was
+   * specified.
+   *
+   * @param scope
+   * @param attrs
+   * @param paginationId
+   * @returns {*}
+   */
+  function makeCurrentPageGetterFn(scope, attrs, paginationId) {
+    var currentPageGetter;
+    if (attrs.currentPage) {
+      currentPageGetter = $parse(attrs.currentPage);
+    } else {
+      // If the current-page attribute was not set, we'll make our own.
+      // Replace any non-alphanumeric characters which might confuse
+      // the $parse service and give unexpected results.
+      // See https://github.com/michaelbromley/angularUtils/issues/233
+      var defaultCurrentPage =
+          (paginationId + '__currentPage').replace(/\W/g, '_');
+      scope[defaultCurrentPage] = 1;
+      currentPageGetter = $parse(defaultCurrentPage);
+    }
+    return currentPageGetter;
+  }
+}
+
+/**
+ * This is a helper directive that allows correct compilation when in
+ * multi-element mode (ie dir-paginate-start, dir-paginate-end). It is
+ * dynamically added to all elements in the dir-paginate compile function, and
+ * it prevents further compilation of any inner directives. It is then removed
+ * in the link function, and all inner directives are then manually compiled.
+ */
+function noCompileDirective() {
+  return {priority: 5000, terminal: true};
+}
+
+function dirPaginationControlsTemplateInstaller($templateCache) {
+  $templateCache.put(
+      'app.common.directives.dirPagination.template',
+      '<ul class="pagination" ng-if="1 < pages.length || !autoHide"><li ng-if="boundaryLinks" ng-class="{ disabled : pagination.current == 1 }"><a href="" ng-click="setCurrent(1)">&laquo;</a></li><li ng-if="directionLinks" ng-class="{ disabled : pagination.current == 1 }"><a href="" ng-click="setCurrent(pagination.current - 1)">&lsaquo;</a></li><li ng-repeat="pageNumber in pages track by tracker(pageNumber, $index)" ng-class="{ active : pagination.current == pageNumber, disabled : pageNumber == \'...\' || ( ! autoHide && pages.length === 1 ) }"><a href="" ng-click="setCurrent(pageNumber)">{{ pageNumber }}</a></li><li ng-if="directionLinks" ng-class="{ disabled : pagination.current == pagination.last }"><a href="" ng-click="setCurrent(pagination.current + 1)">&rsaquo;</a></li><li ng-if="boundaryLinks"  ng-class="{ disabled : pagination.current == pagination.last }"><a href="" ng-click="setCurrent(pagination.last)">&raquo;</a></li></ul>');
+}
+
+function dirPaginationControlsDirective(paginationService, paginationTemplate) {
+  var numberRegex = /^\d+$/;
+
+  var DDO = {
+    restrict: 'AE',
+    scope:
+        {maxSize: '=?', onPageChange: '&?', paginationId: '=?', autoHide: '=?'},
+    link: dirPaginationControlsLinkFn
+  };
+
+  // We need to check the paginationTemplate service to see whether a template
+  // path or string has been specified, and add the `template` or `templateUrl`
+  // property to the DDO as appropriate. The order of priority to decide which
+  // template to use is (highest priority first):
+  // 1. paginationTemplate.getString()
+  // 2. attrs.templateUrl
+  // 3. paginationTemplate.getPath()
+  var templateString = paginationTemplate.getString();
+  if (templateString !== undefined) {
+    DDO.template = templateString;
+  } else {
+    DDO.templateUrl = function(elem, attrs) {
+      return attrs.templateUrl || paginationTemplate.getPath();
+    };
+  }
+  return DDO;
+
+  function dirPaginationControlsLinkFn(scope, element, attrs) {
+    // rawId is the un-interpolated value of the pagination-id attribute. This
+    // is only important when the corresponding dir-paginate directive has not
+    // yet been linked (e.g. if it is inside an ng-if block), and in that case
+    // it prevents this controls directive from assuming that there is no
+    // corresponding dir-paginate directive and wrongly throwing an exception.
+    var rawId = attrs.paginationId || DEFAULT_ID;
+    var paginationId = scope.paginationId || attrs.paginationId || DEFAULT_ID;
+
+    if (!paginationService.isRegistered(paginationId) &&
+        !paginationService.isRegistered(rawId)) {
+      var idMessage =
+          (paginationId !== DEFAULT_ID) ? ' (id: ' + paginationId + ') ' : ' ';
+      if (window.console) {
+        console.warn(
+            'Pagination directive: the pagination controls' + idMessage +
+            'cannot be used without the corresponding pagination directive, which was not found at link time.');
+      }
+    }
+
+    if (!scope.maxSize) {
+      scope.maxSize = 9;
+    }
+    scope.autoHide = scope.autoHide === undefined ? true : scope.autoHide;
+    scope.directionLinks = angular.isDefined(attrs.directionLinks) ?
+        scope.$parent.$eval(attrs.directionLinks) :
+        true;
+    scope.boundaryLinks = angular.isDefined(attrs.boundaryLinks) ?
+        scope.$parent.$eval(attrs.boundaryLinks) :
+        false;
+
+    var paginationRange = Math.max(scope.maxSize, 5);
+    scope.pages = [];
+    scope.pagination = {last: 1, current: 1};
+    scope.range = {lower: 1, upper: 1, total: 1};
+
+    scope.$watch('maxSize', function(val) {
+      if (val) {
+        paginationRange = Math.max(scope.maxSize, 5);
+        generatePagination();
+      }
+    });
+
+    scope.$watch(
+        function() {
+          if (paginationService.isRegistered(paginationId)) {
+            return (paginationService.getCollectionLength(paginationId) + 1) *
+                paginationService.getItemsPerPage(paginationId);
+          }
+        },
+        function(length) {
+          if (0 < length) {
+            generatePagination();
+          }
+        });
+
+    scope.$watch(
+        function() {
+          if (paginationService.isRegistered(paginationId)) {
+            return (paginationService.getItemsPerPage(paginationId));
+          }
+        },
+        function(current, previous) {
+          if (current != previous && typeof previous !== 'undefined') {
+            goToPage(scope.pagination.current);
+          }
+        });
+
+    scope.$watch(
+        function() {
+          if (paginationService.isRegistered(paginationId)) {
+            return paginationService.getCurrentPage(paginationId);
+          }
+        },
+        function(currentPage, previousPage) {
+          if (currentPage != previousPage) {
+            goToPage(currentPage);
+          }
+        });
+
+    scope.setCurrent = function(num) {
+      if (paginationService.isRegistered(paginationId) &&
+          isValidPageNumber(num)) {
+        num = parseInt(num, 10);
+        paginationService.setCurrentPage(paginationId, num);
+      }
+    };
+
+    /**
+     * Custom "track by" function which allows for duplicate "..." entries on
+     * long lists, yet fixes the problem of wrongly-highlighted links which
+     * happens when using "track by $index" - see
+     * https://github.com/michaelbromley/angularUtils/issues/153
+     * @param id
+     * @param index
+     * @returns {string}
+     */
+    scope.tracker = function(id, index) {
+      return id + '_' + index;
+    };
+
+    function goToPage(num) {
+      if (paginationService.isRegistered(paginationId) &&
+          isValidPageNumber(num)) {
+        var oldPageNumber = scope.pagination.current;
+
+        scope.pages = generatePagesArray(
+            num, paginationService.getCollectionLength(paginationId),
+            paginationService.getItemsPerPage(paginationId), paginationRange);
+        scope.pagination.current = num;
+        updateRangeValues();
+
+        // if a callback has been set, then call it with the page number as the
+        // first argument and the previous page number as a second argument
+        if (scope.onPageChange) {
+          scope.onPageChange(
+              {newPageNumber: num, oldPageNumber: oldPageNumber});
+        }
+      }
+    }
+
+    function generatePagination() {
+      if (paginationService.isRegistered(paginationId)) {
+        var page =
+            parseInt(paginationService.getCurrentPage(paginationId)) || 1;
+        scope.pages = generatePagesArray(
+            page, paginationService.getCollectionLength(paginationId),
+            paginationService.getItemsPerPage(paginationId), paginationRange);
+        scope.pagination.current = page;
+        scope.pagination.last = scope.pages[scope.pages.length - 1];
+        if (scope.pagination.last < scope.pagination.current) {
+          scope.setCurrent(scope.pagination.last);
+        } else {
+          updateRangeValues();
+        }
+      }
+    }
+
+    /**
+     * This function updates the values (lower, upper, total) of the
+     * `scope.range` object, which can be used in the pagination template to
+     * display the current page range, e.g. "showing 21 - 40 of 144 results";
+     */
+    function updateRangeValues() {
+      if (paginationService.isRegistered(paginationId)) {
+        var currentPage = paginationService.getCurrentPage(paginationId),
+            itemsPerPage = paginationService.getItemsPerPage(paginationId),
+            totalItems = paginationService.getCollectionLength(paginationId);
+
+        scope.range.lower = (currentPage - 1) * itemsPerPage + 1;
+        scope.range.upper = Math.min(currentPage * itemsPerPage, totalItems);
+        scope.range.total = totalItems;
+      }
+    }
+    function isValidPageNumber(num) {
+      return (
+          numberRegex.test(num) && (0 < num && num <= scope.pagination.last));
+    }
+  }
+
+  /**
+   * Generate an array of page numbers (or the '...' string) which is used in an
+   * ng-repeat to generate the links used in pagination
+   *
+   * @param currentPage
+   * @param rowsPerPage
+   * @param paginationRange
+   * @param collectionLength
+   * @returns {Array}
+   */
+  function generatePagesArray(
+      currentPage, collectionLength, rowsPerPage, paginationRange) {
+    var pages = [];
+    var totalPages = Math.ceil(collectionLength / rowsPerPage);
+    var halfWay = Math.ceil(paginationRange / 2);
+    var position;
+
+    if (currentPage <= halfWay) {
+      position = 'start';
+    } else if (totalPages - halfWay < currentPage) {
+      position = 'end';
+    } else {
+      position = 'middle';
+    }
+
+    var ellipsesNeeded = paginationRange < totalPages;
+    var i = 1;
+    while (i <= totalPages && i <= paginationRange) {
+      var pageNumber =
+          calculatePageNumber(i, currentPage, paginationRange, totalPages);
+
+      var openingEllipsesNeeded =
+          (i === 2 && (position === 'middle' || position === 'end'));
+      var closingEllipsesNeeded =
+          (i === paginationRange - 1 &&
+           (position === 'middle' || position === 'start'));
+      if (ellipsesNeeded && (openingEllipsesNeeded || closingEllipsesNeeded)) {
+        pages.push('...');
+      } else {
+        pages.push(pageNumber);
+      }
+      i++;
+    }
+    return pages;
+  }
+
+  /**
+   * Given the position in the sequence of pagination links [i], figure out what
+   * page number corresponds to that position.
+   *
+   * @param i
+   * @param currentPage
+   * @param paginationRange
+   * @param totalPages
+   * @returns {*}
+   */
+  function calculatePageNumber(i, currentPage, paginationRange, totalPages) {
+    var halfWay = Math.ceil(paginationRange / 2);
+    if (i === paginationRange) {
+      return totalPages;
+    } else if (i === 1) {
+      return i;
+    } else if (paginationRange < totalPages) {
+      if (totalPages - halfWay < currentPage) {
+        return totalPages - paginationRange + i;
+      } else if (halfWay < currentPage) {
+        return currentPage - halfWay + i;
+      } else {
+        return i;
+      }
+    } else {
+      return i;
+    }
+  }
+}
+
+/**
+ * This filter slices the collection into pages based on the current page number
+ * and number of items per page.
+ * @param paginationService
+ * @returns {Function}
+ */
+function itemsPerPageFilter(paginationService) {
+  return function(collection, itemsPerPage, paginationId) {
+    if (typeof (paginationId) === 'undefined') {
+      paginationId = DEFAULT_ID;
+    }
+    if (!paginationService.isRegistered(paginationId)) {
+      throw 'pagination directive: the itemsPerPage id argument (id: ' +
+          paginationId + ') does not match a registered pagination-id.';
+    }
+    var end;
+    var start;
+    if (angular.isObject(collection)) {
+      itemsPerPage = parseInt(itemsPerPage) || 9999999999;
+      if (paginationService.isAsyncMode(paginationId)) {
+        start = 0;
+      } else {
+        start =
+            (paginationService.getCurrentPage(paginationId) - 1) * itemsPerPage;
+      }
+      end = start + itemsPerPage;
+      paginationService.setItemsPerPage(paginationId, itemsPerPage);
+
+      if (collection instanceof Array) {
+        // the array just needs to be sliced
+        return collection.slice(start, end);
+      } else {
+        // in the case of an object, we need to get an array of keys, slice
+        // that, then map back to the original object.
+        var slicedObject = {};
+        angular.forEach(keys(collection).slice(start, end), function(key) {
+          slicedObject[key] = collection[key];
+        });
+        return slicedObject;
+      }
+    } else {
+      return collection;
+    }
+  };
+}
+
+/**
+ * Shim for the Object.keys() method which does not exist in IE < 9
+ * @param obj
+ * @returns {Array}
+ */
+function keys(obj) {
+  if (!Object.keys) {
+    var objKeys = [];
+    for (var i in obj) {
+      if (obj.hasOwnProperty(i)) {
+        objKeys.push(i);
+      }
+    }
+    return objKeys;
+  } else {
+    return Object.keys(obj);
+  }
+}
+
+/**
+ * This service allows the various parts of the module to communicate and stay
+ * in sync.
+ */
+function paginationService() {
+  var instances = {};
+  var lastRegisteredInstance;
+
+  this.registerInstance = function(instanceId) {
+    if (typeof instances[instanceId] === 'undefined') {
+      instances[instanceId] = {asyncMode: false};
+      lastRegisteredInstance = instanceId;
+    }
+  };
+
+  this.deregisterInstance = function(instanceId) {
+    delete instances[instanceId];
+  };
+
+  this.isRegistered = function(instanceId) {
+    return (typeof instances[instanceId] !== 'undefined');
+  };
+
+  this.getLastInstanceId = function() {
+    return lastRegisteredInstance;
+  };
+
+  this.setCurrentPageParser = function(instanceId, val, scope) {
+    instances[instanceId].currentPageParser = val;
+    instances[instanceId].context = scope;
+  };
+  this.setCurrentPage = function(instanceId, val) {
+    instances[instanceId].currentPageParser.assign(
+        instances[instanceId].context, val);
+  };
+  this.getCurrentPage = function(instanceId) {
+    var parser = instances[instanceId].currentPageParser;
+    return parser ? parser(instances[instanceId].context) : 1;
+  };
+
+  this.setItemsPerPage = function(instanceId, val) {
+    instances[instanceId].itemsPerPage = val;
+  };
+  this.getItemsPerPage = function(instanceId) {
+    return instances[instanceId].itemsPerPage;
+  };
+
+  this.setCollectionLength = function(instanceId, val) {
+    instances[instanceId].collectionLength = val;
+  };
+  this.getCollectionLength = function(instanceId) {
+    return instances[instanceId].collectionLength;
+  };
+
+  this.setAsyncModeTrue = function(instanceId) {
+    instances[instanceId].asyncMode = true;
+  };
+
+  this.setAsyncModeFalse = function(instanceId) {
+    instances[instanceId].asyncMode = false;
+  };
+
+  this.isAsyncMode = function(instanceId) {
+    return instances[instanceId].asyncMode;
+  };
+}
+
+/**
+ * This provider allows global configuration of the template path used by the
+ * dir-pagination-controls directive.
+ */
+function paginationTemplateProvider() {
+  var templatePath = 'app.common.directives.dirPagination.template';
+  var templateString;
+
+  /**
+   * Set a templateUrl to be used by all instances of <dir-pagination-controls>
+   * @param {String} path
+   */
+  this.setPath = function(path) {
+    templatePath = path;
+  };
+
+  /**
+   * Set a string of HTML to be used as a template by all instances
+   * of <dir-pagination-controls>. If both a path *and* a string have been set,
+   * the string takes precedence.
+   * @param {String} str
+   */
+  this.setString = function(str) {
+    templateString = str;
+  };
+
+  this.$get = function() {
+    return {
+      getPath: function() {
+        return templatePath;
+      },
+      getString: function() {
+        return templateString;
+      }
+    };
+  };
+}
+})();
