text:   function sequenceEqualArray(first, second, comparer) {
      return new AnonymousObservable(function (observer) {
        var count = 0, len = second.length;
        return first.subscribe(function (value) {
          var equal = false;
          try {
            count < len && (equal = comparer(value, second[count++]));
          } catch (e) {
            observer.onError(e);
            return;
          }
          if (!equal) {
            observer.onNext(false);
            observer.onCompleted();
          }
        }, observer.onError.bind(observer), function () {
          observer.onNext(count === len);
          observer.onCompleted();
        });
      });
    }
  
    /**
     *  Determines whether two sequences are equal by comparing the elements pairwise using a specified equality comparer.
     *
     * @example
     * var res = res = source.sequenceEqual([1,2,3]);
     * var res = res = source.sequenceEqual([{ value: 42 }], function (x, y) { return x.value === y.value; });
     * 3 - res = source.sequenceEqual(Rx.Observable.returnValue(42));
     * 4 - res = source.sequenceEqual(Rx.Observable.returnValue({ value: 42 }), function (x, y) { return x.value === y.value; });
     * @param {Observable} second Second observable sequence or array to compare.
     * @param {Function} [comparer] Comparer used to compare elements of both sequences.
     * @returns {Observable} An observable sequence that contains a single element which indicates whether both sequences are of equal length and their corresponding elements are equal according to the specified equality comparer.
     */
    observableProto.sequenceEqual = function (second, comparer) {
      var first = this;
      comparer || (comparer = defaultComparer);
      if (Array.isArray(second)) {
        return sequenceEqualArray(first, second, comparer);
      }
      return new AnonymousObservable(function (observer) {
        var donel = false, doner = false, ql = [], qr = [];
        var subscription1 = first.subscribe(function (x) {
          var equal, v;
          if (qr.length > 0) {
            v = qr.shift();
            try {
              equal = comparer(v, x);
            } catch (e) {
              observer.onError(e);
              return;
            }
            if (!equal) {
              observer.onNext(false);
              observer.onCompleted();
            }
          } else if (doner) {
            observer.onNext(false);
            observer.onCompleted();
          } else {
            ql.push(x);
          }
        }, observer.onError.bind(observer), function () {
          donel = true;
          if (ql.length === 0) {
            if (qr.length > 0) {
              observer.onNext(false);
              observer.onCompleted();
            } else if (doner) {
              observer.onNext(true);
              observer.onCompleted();
            }
          }
        });
  
        isPromise(second) && (second = observableFromPromise(second));
        var subscription2 = second.subscribe(function (x) {
          var equal;
          if (ql.length > 0) {
            var v = ql.shift();
            try {
              equal = comparer(v, x);
            } catch (exception) {
              observer.onError(exception);
              return;
            }
            if (!equal) {
              observer.onNext(false);
              observer.onCompleted();
            }
          } else if (donel) {
            observer.onNext(false);
            observer.onCompleted();
          } else {
            qr.push(x);
          }
        }, observer.onError.bind(observer), function () {
          doner = true;
          if (qr.length === 0) {
            if (ql.length > 0) {
              observer.onNext(false);
              observer.onCompleted();
            } else if (donel) {
              observer.onNext(true);
              observer.onCompleted();
            }
          }
        });
        return new CompositeDisposable(subscription1, subscription2);
      });
    };
  