  /**
   * Gets a scheduler that schedules work as soon as possible on the current thread.
   */
  var currentThreadScheduler = Scheduler.currentThread = (function () {
    var queue;

    function runTrampoline (q) {
      var item;
      while (q.length > 0) {
        item = q.dequeue();
        if (!item.isCancelled()) {
          // Note, do not schedule blocking work!
          while (item.dueTime - Scheduler.now() > 0) {
          }
          if (!item.isCancelled()) {
            item.invoke();
          }
        }
      }
    }

    function scheduleNow(state, action) {
      return this.scheduleWithRelativeAndState(state, 0, action);
    }

    function scheduleRelative(state, dueTime, action) {
      var dt = this.now() + Scheduler.normalize(dueTime),
          si = new ScheduledItem(this, state, action, dt);

      if (!queue) {
        queue = new PriorityQueue(4);
        queue.enqueue(si);
        try {
          runTrampoline(queue);
        } catch (e) {
          throw e;
        } finally {
          queue = null;
        }
      } else {
        queue.enqueue(si);
      }
      return si.disposable;
    }

    function scheduleAbsolute(state, dueTime, action) {
      return this.scheduleWithRelativeAndState(state, dueTime - this.now(), action);
    }

    var currentScheduler = new Scheduler(defaultNow, scheduleNow, scheduleRelative, scheduleAbsolute);

    currentScheduler.scheduleRequired = function () { return !queue; };
    currentScheduler.ensureTrampoline = function (action) {
      if (!queue) { this.schedule(action); } else { action(); }
    };

    return currentScheduler;
  }());
