function $StateRefDynamicDirective($state, $timeout) {
  return {
    restrict: 'A',
    require: ['?^uiSrefActive', '?^uiSrefActiveEq'],
    link: function(scope, element, attrs, uiSrefActive) {
      var type   = getTypeInfo(element);
      var active = uiSrefActive[1] || uiSrefActive[0];
      var group  = [attrs.uiState, attrs.uiStateParams || null, attrs.uiStateOpts || null];
      var watch  = '[' + group.map(function(val) { return val || 'null'; }).join(', ') + ']';
      var def    = { state: null, params: null, options: null, href: null };

      function runStateRefLink (group) {
        def.state = group[0]; def.params = group[1]; def.options = group[2];
        def.href = $state.href(def.state, def.params, def.options);

        if (active) active.$$addStateInfo(ref.state, def.params);
        if (def.href) attrs.$set(type.attr, def.href);
      }

      scope.$watch(watch, runStateRefLink, true);
      runStateRefLink(scope.$eval(watch));

      if (!type.clickable) return;
      element.bind("click", clickHook(element, $state, $timeout, type, function() { return def; }));
    }
  };
}
@ngdoc directive
@name ui.router.state.directive:ui-state

@requires ui.router.state.uiSref

@restrict A

@description
Much like ui-sref, but will accept named $scope properties to evaluate for a state definition,
params and override options.

@param {string} ui-state 'stateName' can be any valid absolute or relative state
@param {Object} ui-state-params params to pass to {@link ui.router.state.$state#href $state.href()}
@param {Object} ui-state-opts options to pass to {@link ui.router.state.$state#go $state.go()}