text:   /**
     *  Represents the result of an asynchronous operation.
     *  The last value before the OnCompleted notification, or the error received through OnError, is sent to all subscribed observers.
     */
    var AsyncSubject = Rx.AsyncSubject = (function (__super__) {
  
      function subscribe(observer) {
        checkDisposed.call(this);
  
        if (!this.isStopped) {
          this.observers.push(observer);
          return new InnerSubscription(this, observer);
        }
  
        if (this.hasError) {
          observer.onError(this.error);
        } else if (this.hasValue) {
          observer.onNext(this.value);
          observer.onCompleted();
        } else {
          observer.onCompleted();
        }
  
        return disposableEmpty;
      }
  
      inherits(AsyncSubject, __super__);
  
      /**
       * Creates a subject that can only receive one value and that value is cached for all future observations.
       * @constructor
       */
      function AsyncSubject() {
        __super__.call(this, subscribe);
  
        this.isDisposed = false;
        this.isStopped = false;
        this.hasValue = false;
        this.observers = [];
        this.hasError = false;
      }
  
      addProperties(AsyncSubject.prototype, Observer, {
        /**
         * Indicates whether the subject has observers subscribed to it.
         * @returns {Boolean} Indicates whether the subject has observers subscribed to it.
         */
        hasObservers: function () {
          checkDisposed.call(this);
          return this.observers.length > 0;
        },
        /**
         * Notifies all subscribed observers about the end of the sequence, also causing the last received value to be sent out (if any).
         */
        onCompleted: function () {
          var i, len;
          checkDisposed.call(this);
          if (!this.isStopped) {
            this.isStopped = true;
            var os = this.observers.slice(0), len = os.length;
  
            if (this.hasValue) {
              for (i = 0; i < len; i++) {
                var o = os[i];
                o.onNext(this.value);
                o.onCompleted();
              }
            } else {
              for (i = 0; i < len; i++) {
                os[i].onCompleted();
              }
            }
  
            this.observers.length = 0;
          }
        },
        /**
         * Notifies all subscribed observers about the error.
         * @param {Mixed} error The Error to send to all observers.
         */
        onError: function (error) {
          checkDisposed.call(this);
          if (!this.isStopped) {
            var os = this.observers.slice(0);
            this.isStopped = true;
            this.hasError = true;
            this.error = error;
  
            for (var i = 0, len = os.length; i < len; i++) {
              os[i].onError(error);
            }
  
            this.observers.length = 0;
          }
        },
        /**
         * Sends a value to the subject. The last value received before successful termination will be sent to all subscribed and future observers.
         * @param {Mixed} value The value to store in the subject.
         */
        onNext: function (value) {
          checkDisposed.call(this);
          if (this.isStopped) { return; }
          this.value = value;
          this.hasValue = true;
        },
        /**
         * Unsubscribe all observers and release resources.
         */
        dispose: function () {
          this.isDisposed = true;
          this.observers = null;
          this.exception = null;
          this.value = null;
        }
      });
  
      return AsyncSubject;
    }(Observable));
  