function actionSheet(opts) {
    var scope = $rootScope.$new(true);

    extend(scope, {
      cancel: noop,
      destructiveButtonClicked: noop,
      buttonClicked: noop,
      $deregisterBackButton: noop,
      buttons: [],
      cancelOnStateChange: true
    }, opts || {});

    function textForIcon(text) {
      if (text && /icon/.test(text)) {
        scope.$actionSheetHasIcon = true;
      }
    }

    for (var x = 0; x < scope.buttons.length; x++) {
      textForIcon(scope.buttons[x].text);
    }
    textForIcon(scope.cancelText);
    textForIcon(scope.destructiveText);

    // Compile the template
    var element = scope.element = $compile('<ion-action-sheet ng-class="cssClass" buttons="buttons"></ion-action-sheet>')(scope);

    // Grab the sheet element for animation
    var sheetEl = jqLite(element[0].querySelector('.action-sheet-wrapper'));

    var stateChangeListenDone = scope.cancelOnStateChange ?
      $rootScope.$on('$stateChangeSuccess', function() { scope.cancel(); }) :
      noop;

    // removes the actionSheet from the screen
    scope.removeSheet = function(done) {
      if (scope.removed) return;

      scope.removed = true;
      sheetEl.removeClass('action-sheet-up');
      $timeout(function() {
        // wait to remove this due to a 300ms delay native
        // click which would trigging whatever was underneath this
        $ionicBody.removeClass('action-sheet-open');
      }, 400);
      scope.$deregisterBackButton();
      stateChangeListenDone();

      $animate.removeClass(element, 'active').then(function() {
        scope.$destroy();
        element.remove();
        // scope.cancel.$scope is defined near the bottom
        scope.cancel.$scope = sheetEl = null;
        (done || noop)(opts.buttons);
      });
    };

    scope.showSheet = function(done) {
      if (scope.removed) return;

      $ionicBody.append(element)
                .addClass('action-sheet-open');

      $animate.addClass(element, 'active').then(function() {
        if (scope.removed) return;
        (done || noop)();
      });
      $timeout(function() {
        if (scope.removed) return;
        sheetEl.addClass('action-sheet-up');
      }, 20, false);
    };

    // registerBackButtonAction returns a callback to deregister the action
    scope.$deregisterBackButton = $ionicPlatform.registerBackButtonAction(
      function() {
        $timeout(scope.cancel);
      },
      IONIC_BACK_PRIORITY.actionSheet
    );

    // called when the user presses the cancel button
    scope.cancel = function() {
      // after the animation is out, call the cancel callback
      scope.removeSheet(opts.cancel);
    };

    scope.buttonClicked = function(index) {
      // Check if the button click event returned true, which means
      // we can close the action sheet
      if (opts.buttonClicked(index, opts.buttons[index]) === true) {
        scope.removeSheet();
      }
    };

    scope.destructiveButtonClicked = function() {
      // Check if the destructive button click event returned true, which means
      // we can close the action sheet
      if (opts.destructiveButtonClicked() === true) {
        scope.removeSheet();
      }
    };

    scope.showSheet();

    // Expose the scope on $ionicActionSheet's return value for the sake
    // of testing it.
    scope.cancel.$scope = scope;

    return scope.cancel;
  }
@ngdoc method
@name $ionicActionSheet#show
@description
Load and return a new action sheet.

A new isolated scope will be created for the
action sheet and the new element will be appended into the body.

@param {object} options The options for this ActionSheet. Properties:

 - `[Object]` `buttons` Which buttons to show.  Each button is an object with a `text` field.
 - `{string}` `titleText` The title to show on the action sheet.
 - `{string=}` `cancelText` the text for a 'cancel' button on the action sheet.
 - `{string=}` `destructiveText` The text for a 'danger' on the action sheet.
 - `{function=}` `cancel` Called if the cancel button is pressed, the backdrop is tapped or
    the hardware back button is pressed.
 - `{function=}` `buttonClicked` Called when one of the non-destructive buttons is clicked,
    with the index of the button that was clicked and the button object. Return true to close
    the action sheet, or false to keep it opened.
 - `{function=}` `destructiveButtonClicked` Called when the destructive button is clicked.
    Return true to close the action sheet, or false to keep it opened.
 -  `{boolean=}` `cancelOnStateChange` Whether to cancel the actionSheet when navigating
    to a new state.  Default true.
 - `{string}` `cssClass` The custom CSS class name.

@returns {function} `hideSheet` A function which, when called, hides & cancels the action sheet.