hunk.code_window: var Map = require('../../dist/cjs/util/Map').Map;
   var Rx = require('../../dist/cjs/Rx');
   var polyfillSymbol = SymbolShim.polyfillSymbol;
   var ensureIterator = SymbolShim.ensureIterator;
   describe('SymbolShim', function () {
     it('should setup symbol if root does not have it', function () {
       var root = {};
       var result = polyfillSymbol(root);
       expect(root.Symbol).toBeDefined();
  
hunk.labels: keep keep keep keep keep replace keep keep keep keep keep
hunk.after_edit: describe('SymbolShim.polyfillSymbol', function () {
     it('should polyfill Symbol to be a function that returns a primitive that is unique', function () {
       var Symbol = polyfillSymbol({ });
       expect(typeof Symbol).toBe('function');
       var x = Symbol('test');
       var y = Symbol('test');
       expect(x !== y).toBe(true); // should be obvious, but this is the important part.
       expect(x).toBe('@@Symbol(test):0');
       expect(y).toBe('@@Symbol(test):1');
     });
  
hunk.file_path: spec/util/SymbolShim-spec.js
hunk.type: replace
file: import {Operator} from '../Operator';
  import {Observable} from '../Observable';
  import {PromiseObservable} from '../observable/fromPromise';
  import {Subscriber} from '../Subscriber';
  import {Subscription} from '../Subscription';
  
  import {tryCatch} from '../util/tryCatch';
  import {isPromise} from '../util/isPromise';
  import {errorObject} from '../util/errorObject';
  
  export function debounce<T>(durationSelector: (value: T) => Observable<any> | Promise<any>): Observable<T> {
    return this.lift(new DebounceOperator(durationSelector));
  }
  
  class DebounceOperator<T, R> implements Operator<T, R> {
    constructor(private durationSelector: (value: T) => Observable<any> | Promise<any>) {
    }
  
    call(observer: Subscriber<T>): Subscriber<T> {
      return new DebounceSubscriber(observer, this.durationSelector);
    }
  }
  
  class DebounceSubscriber<T> extends Subscriber<T> {
    private debouncedSubscription: Subscription<any> = null;
    private lastValue: any = null;
    private _index: number = 0;
    get index() {
      return this._index;
    }
  
    constructor(destination: Subscriber<T>,
                private durationSelector: (value: T) => Observable<any> | Promise<any>) {
      super(destination);
    }
  
    _next(value: T) {
      const destination = this.destination;
      const currentIndex = ++this._index;
      let debounce = tryCatch(this.durationSelector)(value);
  
      if (debounce === errorObject) {
        destination.error(errorObject.e);
      } else {
        if (isPromise(debounce)) {
          debounce = PromiseObservable.create(debounce);
        }
  
        this.lastValue = value;
        this.clearDebounce();
        this.add(this.debouncedSubscription = debounce._subscribe(new DurationSelectorSubscriber(this, currentIndex)));
      }
    }
  
    _complete() {
      this.debouncedNext();
      this.destination.complete();
    }
  
    debouncedNext(): void {
      this.clearDebounce();
      if (this.lastValue != null) {
        this.destination.next(this.lastValue);
        this.lastValue = null;
      }
    }
  
    private clearDebounce(): void {
      const debouncedSubscription = this.debouncedSubscription;
  
      if (debouncedSubscription) {
        debouncedSubscription.unsubscribe();
        this.remove(debouncedSubscription);
        this.debouncedSubscription = null;
      }
    }
  }
  
  class DurationSelectorSubscriber<T> extends Subscriber<T> {
    constructor(private parent: DebounceSubscriber<any>,
                private currentIndex: number) {
      super(null);
    }
  
    private debounceNext(): void {
      const parent = this.parent;
  
      if (this.currentIndex === parent.index) {
        parent.debouncedNext();
        if (!this.isUnsubscribed) {
          this.unsubscribe();
        }
      }
    }
  
    _next(unused: T) {
       this.debounceNext();
    }
  
    _error(err) {
      this.parent.error(err);
    }
  
    _complete() {
      this.debounceNext();
    }
  }
  