function mdRadioButtonDirective($mdAria, $mdUtil, $mdTheming) {

  var CHECKED_CSS = 'md-checked';

  return {
    restrict: 'E',
    require: '^mdRadioGroup',
    transclude: true,
    template: '<div class="md-container" md-ink-ripple md-ink-ripple-checkbox>' +
                '<div class="md-off"></div>' +
                '<div class="md-on"></div>' +
              '</div>' +
              '<div ng-transclude class="md-label"></div>',
    link: link
  };

  function link(scope, element, attr, radioGroupController) {
    var lastChecked;

    $mdTheming(element);
    configureAria(element);
    element.addClass('md-auto-horizontal-margin');

    // ngAria overwrites the aria-checked inside a $watch for ngValue.
    // We should defer the initialization until all the watches have fired.
    // This can also be fixed by removing the `lastChecked` check, but that'll
    // cause more DOM manipulation on each digest.
    if (attr.ngValue) {
      $mdUtil.nextTick(initialize, false);
    } else {
      initialize();
    }

    /**
     * Initializes the component.
     */
    function initialize() {
      if (!radioGroupController) {
        throw 'RadioButton: No RadioGroupController could be found.';
      }

      radioGroupController.add(render);
      attr.$observe('value', render);

      element
        .on('click', listener)
        .on('$destroy', function() {
          radioGroupController.remove(render);
        });
    }

    /**
     * On click functionality.
     */
    function listener(ev) {
      if (element[0].hasAttribute('disabled') || radioGroupController.isDisabled()) return;

      scope.$apply(function() {
        radioGroupController.setViewValue(attr.value, ev && ev.type);
      });
    }

    /**
     * Add or remove the `.md-checked` class from the RadioButton (and conditionally its parent).
     * Update the `aria-activedescendant` attribute.
     */
    function render() {
      var checked = radioGroupController.getViewValue() == attr.value;

      if (checked === lastChecked) return;

      if (element[0] && element[0].parentNode &&
          element[0].parentNode.nodeName.toLowerCase() !== 'md-radio-group') {
        // If the radioButton is inside a div, then add class so highlighting will work.
        element.parent().toggleClass(CHECKED_CSS, checked);
      }

      if (checked) {
        radioGroupController.setActiveDescendant(element.attr('id'));
      }

      lastChecked = checked;

      element
        .attr('aria-checked', checked)
        .toggleClass(CHECKED_CSS, checked);
    }

    /**
     * Inject ARIA-specific attributes appropriate for each radio button
     */
    function configureAria(element) {
      element.attr({
        id: attr.id || 'radio_' + $mdUtil.nextUid(),
        role: 'radio',
        'aria-checked': 'false'
      });

      $mdAria.expectWithText(element, 'aria-label');
    }
  }
}
@ngdoc directive
@module material.components.radioButton
@name mdRadioButton

@restrict E

@description
The `<md-radio-button>`directive is the child directive required to be used within `<md-radio-group>` elements.

While similar to the `<input type="radio" ng-model="" value="">` directive,
the `<md-radio-button>` directive provides ink effects, ARIA support, and
supports use within named radio groups.

One of `value` or `ng-value` must be set so that the `md-radio-group`'s model is set properly when the
`md-radio-button` is selected.

@param {string} value The value to which the model should be set when selected.
@param {string} ng-value AngularJS expression which sets the value to which the model should
   be set when selected.
@param {string=} name Property name of the form under which the control is published.
@param {string=} aria-label Adds label to radio button for accessibility.
   Defaults to radio button's text. If no text content is available, a warning will be logged.

@usage
<hljs lang="html">

<md-radio-button value="1" aria-label="Label 1">
  Label 1
</md-radio-button>

<md-radio-button ng-value="specialValue" aria-label="Green">
  Green
</md-radio-button>

</hljs>