function addAriaLiveRegion() {
                // Thanks to google docs for the inspiration behind how to do this
                // XXX: Why is this entire mess nessasary?
                // Because browsers take a lot of coercing to get them to read out live regions
                // http://www.paciellogroup.com/blog/2012/06/html5-accessibility-chops-aria-rolealert-browser-support/
                var ariaNotifierDomElt = '<div ' +
                                           'id="' + grid.id +'-aria-speakable" ' +
                                           'class="ui-grid-a11y-ariascreenreader-speakable ui-grid-offscreen" ' +
                                           'aria-live="assertive" ' +
                                           'role="alert" ' +
                                           'aria-atomic="true" ' +
                                           'aria-hidden="false" ' +
                                           'aria-relevant="additions" ' +
                                           '>' +
                                           '&nbsp;' +
                                         '</div>';

                var ariaNotifier = $compile(ariaNotifierDomElt)($scope);
                $elm.prepend(ariaNotifier);
                $scope.$on(uiGridCellNavConstants.CELL_NAV_EVENT, function (evt, rowCol, modifierDown, originEvt) {
                  /*
                   * If the cell nav event was because of a focus event then we don't want to
                   * change the notifier text.
                   * Reasoning: Voice Over fires a focus events when moving arround the grid.
                   * If the screen reader is handing the grid nav properly then we don't need to
                   * use the alert to notify the user of the movement.
                   * In all other cases we do want a notification event.
                   */
                  if (originEvt && originEvt.type === 'focus') {return;}

                  function setNotifyText(text) {
                    if (text === ariaNotifier.text().trim()) {return;}
                    ariaNotifier[0].style.clip = 'rect(0px,0px,0px,0px)';
                    /*
                     * This is how google docs handles clearing the div. Seems to work better than setting the text of the div to ''
                     */
                    ariaNotifier[0].innerHTML = "";
                    ariaNotifier[0].style.visibility = 'hidden';
                    ariaNotifier[0].style.visibility = 'visible';
                    if (text !== '') {
                      ariaNotifier[0].style.clip = 'auto';
                      /*
                       * The space after the text is something that google docs does.
                       */
                      ariaNotifier[0].appendChild(document.createTextNode(text + " "));
                      ariaNotifier[0].style.visibility = 'hidden';
                      ariaNotifier[0].style.visibility = 'visible';
                    }
                  }

                  function getAppendedColumnHeaderText(col) {
                    return ', ' + i18nService.getSafeText('headerCell.aria.column') + ' ' + col.displayName;
                  }

                  function getCellDisplayValue(currentRowColumn) {
                    var prefix = '';

                    if (currentRowColumn.col.field === 'selectionRowHeaderCol') {
                      // This is the case when the 'selection' feature is used in the grid and the user has moved
                      // to or inside of the left grid container which holds the checkboxes for selecting rows.
                      // This is necessary for Accessibility. Without this a screen reader cannot determine if the row
                      // is or is not currently selected.
                        prefix = (currentRowColumn.row.isSelected ? i18nService.getSafeText('search.aria.selected') : i18nService.getSafeText('search.aria.notSelected')) + ', ';
                      }
                      return prefix + grid.getCellDisplayValue(currentRowColumn.row, currentRowColumn.col);
                    }

                  var values = [];
                  var currentSelection = grid.api.cellNav.getCurrentSelection();
                  for (var i = 0; i < currentSelection.length; i++) {
                    var cellDisplayValue = getCellDisplayValue(currentSelection[i]) + getAppendedColumnHeaderText(currentSelection[i].col);
                    values.push(cellDisplayValue);
                  }
                  setNotifyText(values.toString());
                });
              }
@ngdoc directive
 @name ui.grid.cellNav.directive:uiCellNav
 @element div
 @restrict EA

 @description Adds cell navigation features to the grid columns

 @example
   <example module="app">
   <file name="app.js">
   var app = angular.module('app', ['ui.grid', 'ui.grid.cellNav']);

   app.controller('MainCtrl', ['$scope', function ($scope) {
      $scope.data = [
        { name: 'Bob', title: 'CEO' },
            { name: 'Frank', title: 'Lowly Developer' }
      ];

      $scope.columnDefs = [
        {name: 'name'},
        {name: 'title'}
      ];
    }]);
   </file>
   <file name="index.html">
   <div ng-controller="MainCtrl">
   <div ui-grid="{ data: data, columnDefs: columnDefs }" ui-grid-cellnav></div>
   </div>
   </file>
   </example>