hunk.code_window: orderedStringToNumber = OrderedMap({'a': 1}).updateIn([], 'a')
   orderedStringToNumber = OrderedMap({'a': 1}).updateIn([], 0, val => val + 1)
   /**
    * FIXME: this should also throw an error, the updater is currently allowed to
    * be anything, rather than restricted to be a function.
    */
   orderedStringToNumber = OrderedMap({'a': 1}).updateIn([], 0, 'a')
   orderedStringToNumber = OrderedMap({'a': 1}).mergeIn([], {'b': 2})
   orderedStringToNumber = OrderedMap({'a': 1}).mergeDeepIn([], {'b': 2})
   orderedStringToNumber = OrderedMap({'a': 1}).withMutations(mutable => mutable.set('b', 2))
  
hunk.labels: keep keep keep replace replace replace replace keep keep keep keep keep
hunk.after_edit: // $ExpectError - 'a' is an invalid argument
  
hunk.file_path: type-definitions/tests/immutable-flow.js
hunk.type: replace
file: /**
   * This file provides type definitions for use with the Flow type checker.
   *
   * An important caveat when using these definitions is that the types for
   * `Iterable.Keyed`, `Iterable.Indexed`, `Seq.Keyed`, and so on are stubs.
   * When referring to those types, you can get the proper definitions by
   * importing the types `KeyedIterable`, `IndexedIterable`, `KeyedSeq`, etc.
   * For example,
   *
   *     import { Seq } from 'immutable'
   *     import type { IndexedIterable, IndexedSeq } from 'immutable'
   *
   *     const someSeq: IndexedSeq<number> = Seq.Indexed.of(1, 2, 3)
   *
   *     function takesASeq<T, TS: IndexedIterable<T>>(iter: TS): TS {
   *       return iter.butLast()
   *     }
   *
   *     takesASeq(someSeq)
   *
   * @flow
   */
  
   /*
    * Alias for ECMAScript `Iterable` type, declared in
    * https://github.com/facebook/flow/blob/master/lib/core.js
    *
    * Note that Immutable values implement the `ESIterable` interface.
    */
  
  type IteratorResult<Yield,Return> = {
   done: true,
   value?: Return,
  } | {
   done: false,
   value: Yield,
  };
  
  
  interface _Iterator<Yield,Return,Next> {
     @@iterator(): _Iterator<Yield,Return,Next>;
     next(value?: Next): IteratorResult<Yield,Return>;
  }
  
  
  interface _ESIterable<Yield,Return,Next> {
     @@iterator(): _Iterator<Yield,Return,Next>;
  }
  
  type Iterator<T> = _Iterator<T, void, void>
  type ESIterable<T> = _ESIterable<T,void,void>;
  
  declare module 'immutable' {
  
    declare class _Iterable<K, V, KI, II, SI> {
      static Keyed:   KI;
      static Indexed: II;
      static Set:     SI;
  
      static isIterable(maybeIterable: any): boolean;
      static isKeyed(maybeKeyed: any): boolean;
      static isIndexed(maybeIndexed: any): boolean;
      static isAssociative(maybeAssociative: any): boolean;
      static isOrdered(maybeOrdered: any): boolean;
  
      equals(other: Iterable<K,V>): boolean;
      hashCode(): number;
      get(key: K): V;
      get<V_>(key: K, notSetValue: V_): V|V_;
      has(key: K): boolean;
      includes(value: V): boolean;
      contains(value: V): boolean;
      first(): V;
      last(): V;
  
      getIn<T>(searchKeyPath: ESIterable<any>, notSetValue: T): T;
      getIn<T>(searchKeyPath: ESIterable<any>): T;
      hasIn(searchKeyPath: ESIterable<any>): boolean;
  
      toJS(): any;
      toArray(): V[];
      toObject(): { [key: string]: V };
      toMap(): Map<K,V>;
      toOrderedMap(): OrderedMap<K,V>;
      toSet(): Set<V>;
      toOrderedSet(): OrderedSet<V>;
      toList(): List<V>;
      toStack(): Stack<V>;
      toSeq(): Seq<K,V>;
      toKeyedSeq(): KeyedSeq<K,V>;
      toIndexedSeq(): IndexedSeq<V>;
      toSetSeq(): SetSeq<V>;
  
      keys(): Iterator<K>;
      values(): Iterator<V>;
      entries(): Iterator<[K,V]>;
  
      keySeq(): IndexedSeq<K>;
      valueSeq(): IndexedSeq<V>;
      entrySeq(): IndexedSeq<[K,V]>;
  
      reverse(): this;
      sort(comparator?: (valueA: V, valueB: V) => number): this;
  
      sortBy<C>(
        comparatorValueMapper: (value: V, key: K, iter: this) => C,
        comparator?: (valueA: C, valueB: C) => number
      ): this;
  
      groupBy<G>(
        grouper: (value: V, key: K, iter: this) => G,
        context?: any
      ): KeyedSeq<G, this>;
  
      forEach(
        sideEffect: (value: V, key: K, iter: this) => any,
        context?: any
      ): number;
  
      slice(begin?: number, end?: number): this;
      rest(): this;
      butLast(): this;
      skip(amount: number): this;
      skipLast(amount: number): this;
      skipWhile(predicate: (value: V, key: K, iter: this) => mixed, context?: any): this;
      skipUntil(predicate: (value: V, key: K, iter: this) => mixed, context?: any): this;
      take(amount: number): this;
      takeLast(amount: number): this;
      takeWhile(predicate: (value: V, key: K, iter: this) => mixed, context?: any): this;
      takeUntil(predicate: (value: V, key: K, iter: this) => mixed, context?: any): this;
      flatten(depth?: number): /*this*/Iterable<any,any>;
      flatten(shallow?: boolean): /*this*/Iterable<any,any>;
  
      filter(
        predicate: (value: V, key: K, iter: this) => mixed,
        context?: any
      ): this;
  
      filterNot(
        predicate: (value: V, key: K, iter: this) => mixed,
        context?: any
      ): this;
  
      reduce<R>(
        reducer: (reduction: R, value: V, key: K, iter: this) => R,
        initialReduction?: R,
        context?: any,
      ): R;
  
      reduceRight<R>(
        reducer: (reduction: R, value: V, key: K, iter: this) => R,
        initialReduction?: R,
        context?: any,
      ): R;
  
      every(predicate: (value: V, key: K, iter: this) => mixed, context?: any): boolean;
      some(predicate: (value: V, key: K, iter: this) => mixed, context?: any): boolean;
      join(separator?: string): string;
      isEmpty(): boolean;
      count(predicate?: (value: V, key: K, iter: this) => mixed, context?: any): number;
      countBy<G>(grouper: (value: V, key: K, iter: this) => G, context?: any): Map<G,number>;
  
      find(
        predicate: (value: V, key: K, iter: this) => mixed,
        context?: any,
      ): ?V;
      find<V_>(
        predicate: (value: V, key: K, iter: this) => mixed,
        context: any,
        notSetValue: V_
      ): V|V_;
  
      findLast(
        predicate: (value: V, key: K, iter: this) => mixed,
        context?: any,
      ): ?V;
      findLast<V_>(
        predicate: (value: V, key: K, iter: this) => mixed,
        context: any,
        notSetValue: V_
      ): V|V_;
  
  
      findEntry(predicate: (value: V, key: K, iter: this) => mixed): ?[K,V];
      findLastEntry(predicate: (value: V, key: K, iter: this) => mixed): ?[K,V];
  
      findKey(predicate: (value: V, key: K, iter: this) => mixed, context?: any): ?K;
      findLastKey(predicate: (value: V, key: K, iter: this) => mixed, context?: any): ?K;
  
      keyOf(searchValue: V): ?K;
      lastKeyOf(searchValue: V): ?K;
  
      max(comparator?: (valueA: V, valueB: V) => number): V;
      maxBy<C>(
        comparatorValueMapper: (value: V, key: K, iter: this) => C,
        comparator?: (valueA: C, valueB: C) => number
      ): V;
      min(comparator?: (valueA: V, valueB: V) => number): V;
      minBy<C>(
        comparatorValueMapper: (value: V, key: K, iter: this) => C,
        comparator?: (valueA: C, valueB: C) => number
      ): V;
  
      isSubset(iter: Iterable<any, V>): boolean;
      isSubset(iter: ESIterable<V>): boolean;
      isSuperset(iter: Iterable<any, V>): boolean;
      isSuperset(iter: ESIterable<V>): boolean;
    }
  
    declare class Iterable<K, V> extends _Iterable<K, V, typeof KeyedIterable, typeof IndexedIterable, typeof SetIterable> {}
  
    declare class KeyedIterable<K,V> extends Iterable<K,V> {
      static <K,V>(iter?: ESIterable<[K,V]>): KeyedIterable<K,V>;
      static <K,V>(obj?: { [key: K]: V }): KeyedIterable<K,V>;
  
      @@iterator(): Iterator<[K,V]>;
      toSeq(): KeyedSeq<K,V>;
      flip(): /*this*/KeyedIterable<V,K>;
  
      mapKeys<K_>(
        mapper: (key: K, value: V, iter: this) => K_,
        context?: any
      ): /*this*/KeyedIterable<K_,V>;
  
      mapEntries<K_,V_>(
        mapper: (entry: [K,V], index: number, iter: this) => [K_,V_],
        context?: any
      ): /*this*/KeyedIterable<K_,V_>;
  
      concat(...iters: ESIterable<[K,V]>[]): this;
  
      map<V_>(
        mapper: (value: V, key: K, iter: this) => V_,
        context?: any
      ): /*this*/KeyedIterable<K,V_>;
  
      flatMap<K_, V_>(
        mapper: (value: V, key: K, iter: this) => ESIterable<[K_,V_]>,
        context?: any
      ): /*this*/KeyedIterable<K_,V_>;
  
      flatten(depth?: number): /*this*/KeyedIterable<any,any>;
      flatten(shallow?: boolean): /*this*/KeyedIterable<any,any>;
    }
  
    declare class IndexedIterable<T> extends Iterable<number,T> {
      static <T>(iter?: ESIterable<T>): IndexedIterable<T>;
  
      @@iterator(): Iterator<T>;
      toSeq(): IndexedSeq<T>;
      fromEntrySeq<K,V>(): KeyedSeq<K,V>;
      interpose(separator: T): this;
      interleave(...iterables: ESIterable<T>[]): this;
      splice(
        index: number,
        removeNum: number,
        ...values: T[]
      ): this;
  
      zip<A>(
        a: ESIterable<A>,
        $?: null
      ): IndexedIterable<[T,A]>;
      zip<A,B>(
        a: ESIterable<A>,
        b: ESIterable<B>,
        $?: null
      ): IndexedIterable<[T,A,B]>;
      zip<A,B,C>(
        a: ESIterable<A>,
        b: ESIterable<B>,
        c: ESIterable<C>,
        $?: null
      ): IndexedIterable<[T,A,B,C]>;
      zip<A,B,C,D>(
        a: ESIterable<A>,
        b: ESIterable<B>,
        c: ESIterable<C>,
        d: ESIterable<D>,
        $?: null
      ): IndexedIterable<[T,A,B,C,D]>;
      zip<A,B,C,D,E>(
        a: ESIterable<A>,
        b: ESIterable<B>,
        c: ESIterable<C>,
        d: ESIterable<D>,
        e: ESIterable<E>,
        $?: null
      ): IndexedIterable<[T,A,B,C,D,E]>;
  
      zipWith<A,R>(
        zipper: (value: T, a: A) => R,
        a: ESIterable<A>,
        $?: null
      ): IndexedIterable<R>;
      zipWith<A,B,R>(
        zipper: (value: T, a: A, b: B) => R,
        a: ESIterable<A>,
        b: ESIterable<B>,
        $?: null
      ): IndexedIterable<R>;
      zipWith<A,B,C,R>(
        zipper: (value: T, a: A, b: B, c: C) => R,
        a: ESIterable<A>,
        b: ESIterable<B>,
        c: ESIterable<C>,
        $?: null
      ): IndexedIterable<R>;
      zipWith<A,B,C,D,R>(
        zipper: (value: T, a: A, b: B, c: C, d: D) => R,
        a: ESIterable<A>,
        b: ESIterable<B>,
        c: ESIterable<C>,
        d: ESIterable<D>,
        $?: null
      ): IndexedIterable<R>;
      zipWith<A,B,C,D,E,R>(
        zipper: (value: T, a: A, b: B, c: C, d: D, e: E) => R,
        a: ESIterable<A>,
        b: ESIterable<B>,
        c: ESIterable<C>,
        d: ESIterable<D>,
        e: ESIterable<E>,
        $?: null
      ): IndexedIterable<R>;
  
      indexOf(searchValue: T): number;
      lastIndexOf(searchValue: T): number;
      findIndex(
        predicate: (value: T, index: number, iter: this) => mixed,
        context?: any
      ): number;
      findLastIndex(
        predicate: (value: T, index: number, iter: this) => mixed,
        context?: any
      ): number;
  
      concat(...iters: ESIterable<T>[]): this;
  
      map<U>(
        mapper: (value: T, index: number, iter: this) => U,
        context?: any
      ): /*this*/IndexedIterable<U>;
  
      flatMap<U>(
        mapper: (value: T, index: number, iter: this) => ESIterable<U>,
        context?: any
      ): /*this*/IndexedIterable<U>;
  
      flatten(depth?: number): /*this*/IndexedIterable<any>;
      flatten(shallow?: boolean): /*this*/IndexedIterable<any>;
    }
  
    declare class SetIterable<T> extends Iterable<T,T> {
      static <T>(iter?: ESIterable<T>): SetIterable<T>;
  
      @@iterator(): Iterator<T>;
      toSeq(): SetSeq<T>;
  
      concat(...iters: ESIterable<T>[]): this;
  
      // `map` and `flatMap` cannot be defined further up the hiearchy, because the
      // implementation for `KeyedIterable` allows the value type to change without
      // constraining the key type. That does not work for `SetIterable` - the value
      // and key types *must* match.
      map<U>(
        mapper: (value: T, value: T, iter: this) => U,
        context?: any
      ): /*this*/SetIterable<U>;
  
      flatMap<U>(
        mapper: (value: T, value: T, iter: this) => ESIterable<U>,
        context?: any
      ): /*this*/SetIterable<U>;
  
      flatten(depth?: number): /*this*/SetIterable<any>;
      flatten(shallow?: boolean): /*this*/SetIterable<any>;
    }
  
    declare class Collection<K,V> extends _Iterable<K,V, typeof KeyedCollection, typeof IndexedCollection, typeof SetCollection> {
      size: number;
    }
  
    declare class KeyedCollection<K,V> extends Collection<K,V> mixins KeyedIterable<K,V> {
      toSeq(): KeyedSeq<K,V>;
    }
  
    declare class IndexedCollection<T> extends Collection<number,T> mixins IndexedIterable<T> {
      toSeq(): IndexedSeq<T>;
    }
  
    declare class SetCollection<T> extends Collection<T,T> mixins SetIterable<T> {
      toSeq(): SetSeq<T>;
    }
  
    declare class Seq<K,V> extends _Iterable<K,V, typeof KeyedSeq, typeof IndexedSeq, typeof SetSeq> {
      static <K,V>(iter: KeyedSeq<K,V>):   KeyedSeq<K,V>;
      static <T>  (iter: SetSeq<T>):       SetSeq<K,V>;
      static <T>  (iter?: ESIterable<T>):  IndexedSeq<T>;
      static <K,V>(iter: { [key: K]: V }): KeyedSeq<K,V>;
  
      static isSeq(maybeSeq: any): boolean;
      static of<T>(...values: T[]): IndexedSeq<T>;
  
      size: ?number;
      cacheResult(): this;
      toSeq(): this;
    }
  
    declare class KeyedSeq<K,V> extends Seq<K,V> mixins KeyedIterable<K,V> {
      static <K,V>(iter?: ESIterable<[K,V]>): KeyedSeq<K,V>;
      static <K,V>(iter?: { [key: K]: V }): KeyedSeq<K,V>;
    }
  
    declare class IndexedSeq<T> extends Seq<number,T> mixins IndexedIterable<T> {
      static <T>(iter?: ESIterable<T>): IndexedSeq<T>;
      static of<T>(...values: T[]): IndexedSeq<T>;
    }
  
    declare class SetSeq<T> extends Seq<T,T> mixins SetIterable<T> {
      static <T>(iter?: ESIterable<T>): IndexedSeq<T>;
      static of<T>(...values: T[]): SetSeq<T>;
    }
  
    declare class List<T> extends IndexedCollection<T> {
      static (iterable?: ESIterable<T>): List<T>;
  
      static isList(maybeList: any): boolean;
      static of<T>(...values: T[]): List<T>;
  
      set<U>(index: number, value: U): List<T|U>;
      delete(index: number): this;
      remove(index: number): this;
      insert<U>(index: number, value: U): List<T|U>;
      clear(): this;
      push<U>(...values: U[]): List<T|U>;
      pop(): this;
      unshift<U>(...values: U[]): List<T|U>;
      shift(): this;
  
      update<U>(updater: (value: this) => List<U>): List<U>;
      update<U>(index: number, updater: (value: T) => U): List<T|U>;
      update<U>(index: number, notSetValue: U, updater: (value: T) => U): List<T|U>;
  
      merge<U>(...iterables: ESIterable<U>[]): List<T|U>;
  
      mergeWith<U,V>(
        merger: (previous: T, next: U, key: number) => V,
        ...iterables: ESIterable<U>[]
      ): List<T|U|V>;
  
      mergeDeep<U>(...iterables: ESIterable<U>[]): List<T|U>;
  
      mergeDeepWith<U,V>(
        merger: (previous: T, next: U, key: number) => V,
        ...iterables: ESIterable<U>[]
      ): List<T|U|V>;
  
      setSize(size: number): List<?T>;
      setIn(keyPath: ESIterable<any>, value: any): List<T>;
      deleteIn(keyPath: ESIterable<any>, value: any): this;
      removeIn(keyPath: ESIterable<any>, value: any): this;
  
      updateIn(keyPath: ESIterable<any>, notSetValue: any, value: any): List<T>;
      updateIn(keyPath: ESIterable<any>, value: any): List<T>;
  
      mergeIn(keyPath: ESIterable<any>, ...iterables: ESIterable<any>[]): List<T>;
      mergeDeepIn(keyPath: ESIterable<any>, ...iterables: ESIterable<any>[]): List<T>;
  
      withMutations(mutator: (mutable: this) => any): this;
      asMutable(): this;
      asImmutable(): this;
  
      // Overrides that specialize return types
      map<M>(
        mapper: (value: T, index: number, iter: this) => M,
        context?: any
      ): List<M>;
  
      flatMap<M>(
        mapper: (value: T, index: number, iter: this) => ESIterable<M>,
        context?: any
      ): List<M>;
  
      flatten(depth?: number): /*this*/List<any>;
      flatten(shallow?: boolean): /*this*/List<any>;
    }
  
    declare class Map<K,V> extends KeyedCollection<K,V> {
      static <K, V>(obj?: {[key: K]: V}): Map<K, V>;
      static <K, V>(iterable: ESIterable<[K,V]>): Map<K, V>;
  
      static isMap(maybeMap: any): boolean;
  
      set<K_, V_>(key: K_, value: V_): Map<K|K_, V|V_>;
      delete(key: K): this;
      remove(key: K): this;
      clear(): this;
  
      update<K_,V_>(updater: (value: this) => Map<K_,V_>): Map<K_,V_>;
      update<V_>(key: K, updater: (value: V) => V_): Map<K,V|V_>;
      update<V_>(key: K, notSetValue: V_, updater: (value: V) => V_): Map<K,V|V_>;
  
      merge<K_,V_>(
        ...iterables: (ESIterable<[K_,V_]> | { [key: K_]: V_ })[]
      ): Map<K|K_,V|V_>;
  
      mergeWith<K_,W,X>(
        merger: (previous: V, next: W, key: K) => X,
        ...iterables: (ESIterable<[K_,W]> | { [key: K_]: W })[]
      ): Map<K|K_,V|W|X>;
  
      mergeDeep<K_,V_>(
        ...iterables: (ESIterable<[K_,V_]> | { [key: K_]: V_ })[]
      ): Map<K|K_,V|V_>;
  
      mergeDeepWith<K_,W,X>(
        merger: (previous: V, next: W, key: K) => X,
        ...iterables: (ESIterable<[K_,W]> | { [key: K_]: W })[]
      ): Map<K|K_,V|W|X>;
  
      setIn(keyPath: ESIterable<any>, value: any): Map<K,V>;
      deleteIn(keyPath: ESIterable<any>, value: any): this;
      removeIn(keyPath: ESIterable<any>, value: any): this;
  
      updateIn(keyPath: ESIterable<any>, notSetValue: any, value: any): Map<K,V>;
      updateIn(keyPath: ESIterable<any>, value: any): Map<K,V>;
  
      mergeIn(
        keyPath: ESIterable<K>,
        ...iterables: (ESIterable<K> | { [key: string]: any })[]
      ): Map<K,any>;
      mergeDeepIn(
        keyPath: ESIterable<K>,
        ...iterables: (ESIterable<K> | { [key: string]: any })[]
      ): Map<K,any>;
  
      withMutations(mutator: (mutable: this) => any): this;
      asMutable(): this;
      asImmutable(): this;
  
      // Overrides that specialize return types
      map<V_>(
        mapper: (value: V, key: K, iter: this) => V_,
        context?: any
      ): Map<K,V_>;
  
      flatMap<K_,V_>(
        mapper: (value: V, key: K, iter: this) => ESIterable<[K_,V_]>,
        context?: any
      ): Map<K_,V_>;
  
      flip(): Map<V,K>;
  
      mapKeys<K_>(
        mapper: (key: K, value: V, iter: this) => K_,
        context?: any
      ): Map<K_,V>;
  
      flatten(depth?: number): /*this*/Map<any,any>;
      flatten(shallow?: boolean): /*this*/Map<any,any>;
    }
  
    declare class OrderedMap<K,V> extends KeyedCollection<K,V> {
      static <K, V>(obj?: {[key: K]: V}): OrderedMap<K, V>;
      static <K, V>(iterable: ESIterable<[K,V]>): OrderedMap<K, V>;
      static isOrderedMap(maybeOrderedMap: any): bool;
  
      set<K_, V_>(key: K_, value: V_): OrderedMap<K|K_, V|V_>;
      delete(key: K): this;
      remove(key: K): this;
      clear(): this;
  
      update<K_,V_>(updater: (value: this) => OrderedMap<K_,V_>): OrderedMap<K_,V_>;
      update<V_>(key: K, updater: (value: V) => V_): OrderedMap<K,V|V_>;
      update<V_>(key: K, notSetValue: V_, updater: (value: V) => V_): OrderedMap<K,V|V_>;
  
      merge<K_,V_>(
        ...iterables: (ESIterable<[K_,V_]> | { [key: K_]: V_ })[]
      ): OrderedMap<K|K_,V|V_>;
  
      mergeWith<K_,W,X>(
        merger: (previous: V, next: W, key: K) => X,
        ...iterables: (ESIterable<[K_,W]> | { [key: K_]: W })[]
      ): OrderedMap<K|K_,V|W|X>;
  
      mergeDeep<K_,V_>(
        ...iterables: (ESIterable<[K_,V_]> | { [key: K_]: V_ })[]
      ): OrderedMap<K|K_,V|V_>;
  
      mergeDeepWith<K_,W,X>(
        merger: (previous: V, next: W, key: K) => X,
        ...iterables: (ESIterable<[K_,W]> | { [key: K_]: W })[]
      ): OrderedMap<K|K_,V|W|X>;
  
      setIn(keyPath: ESIterable<any>, value: any): OrderedMap<K,V>;
      deleteIn(keyPath: ESIterable<any>, value: any): this;
      removeIn(keyPath: ESIterable<any>, value: any): this;
  
      updateIn(keyPath: ESIterable<any>, notSetValue: any, value: any): OrderedMap<K,V>;
      updateIn(keyPath: ESIterable<any>, value: any): OrderedMap<K,V>;
  
      mergeIn(
        keyPath: ESIterable<K>,
        ...iterables: (ESIterable<K> | { [key: string]: any })[]
      ): OrderedMap<K,any>;
      mergeDeepIn(
        keyPath: ESIterable<K>,
        ...iterables: (ESIterable<K> | { [key: string]: any })[]
      ): OrderedMap<K,any>;
  
      withMutations(mutator: (mutable: this) => any): this;
      asMutable(): this;
      asImmutable(): this;
  
      // Overrides that specialize return types
      map<V_>(
        mapper: (value: V, key: K, iter: this) => V_,
        context?: any
      ): OrderedMap<K,V_>;
  
      flatMap<K_,V_>(
        mapper: (value: V, key: K, iter: this) => ESIterable<[K_,V_]>,
        context?: any
      ): OrderedMap<K_,V_>;
  
      flip(): OrderedMap<V,K>;
  
      mapKeys<K_>(
        mapper: (key: K, value: V, iter: this) => K_,
        context?: any
      ): OrderedMap<K_,V>;
  
      flatten(depth?: number): /*this*/OrderedMap<any,any>;
      flatten(shallow?: boolean): /*this*/OrderedMap<any,any>
    }
  
    declare class Set<T> extends SetCollection<T> {
      static <T>(iterable: ESIterable<T>): Set<T>;
      static isSet(maybeSet: any): boolean;
      static of<T>(...values: T[]): Set<T>;
      static fromKeys<T>(iter: ESIterable<[T,any]>): Set<T>;
      static fromKeys<K, V>(object: { [key: K]: V }): Set<K>;
      static (_: void): Set<any>;
  
      add<U>(value: U): Set<T|U>;
      delete(value: T): this;
      remove(value: T): this;
      clear(): this;
      union<U>(...iterables: ESIterable<U>[]): Set<T|U>;
      merge<U>(...iterables: ESIterable<U>[]): Set<T|U>;
      intersect<U>(...iterables: ESIterable<U>[]): Set<T&U>;
      subtract<U>(...iterables: ESIterable<U>[]): Set<T>;
  
      withMutations(mutator: (mutable: this) => any): this;
      asMutable(): this;
      asImmutable(): this;
  
      // Overrides that specialize return types
      map<M>(
        mapper: (value: T, value: T, iter: this) => M,
        context?: any
      ): Set<M>;
  
      flatMap<M>(
        mapper: (value: T, value: T, iter: this) => ESIterable<M>,
        context?: any
      ): Set<M>;
  
      flatten(depth?: number): /*this*/Set<any>;
      flatten(shallow?: boolean): /*this*/Set<any>;
    }
  
    // Overrides except for `isOrderedSet` are for specialized return types
    declare class OrderedSet<T> extends Set<T> {
      static <T>(iterable: ESIterable<T>): OrderedSet<T>;
      static of<T>(...values: T[]): OrderedSet<T>;
      static fromKeys<T>(iter: ESIterable<[T,any]>): OrderedSet<T>;
      static fromKeys<K, V>(object: { [key: K]: V }): OrderedSet<K>;
      static (_: void): OrderedSet<any>;
      static isOrderedSet(maybeOrderedSet: any): bool;
  
      add<U>(value: U): OrderedSet<T|U>;
      union<U>(...iterables: ESIterable<U>[]): OrderedSet<T|U>;
      merge<U>(...iterables: ESIterable<U>[]): OrderedSet<T|U>;
      intersect<U>(...iterables: ESIterable<U>[]): OrderedSet<T&U>;
      subtract<U>(...iterables: ESIterable<U>[]): OrderedSet<T>;
  
      map<M>(
        mapper: (value: T, value: T, iter: this) => M,
        context?: any
      ): OrderedSet<M>;
  
      flatMap<M>(
        mapper: (value: T, value: T, iter: this) => ESIterable<M>,
        context?: any
      ): OrderedSet<M>;
  
      flatten(depth?: number): /*this*/OrderedSet<any>;
      flatten(shallow?: boolean): /*this*/OrderedSet<any>;
    }
  
    declare class Stack<T> extends IndexedCollection<T> {
      static <T>(iterable?: ESIterable<T>): Stack<T>;
  
      static isStack(maybeStack: any): boolean;
      static of<T>(...values: T[]): Stack<T>;
  
      peek(): T;
      clear(): this;
      unshift<U>(...values: U[]): Stack<T|U>;
      unshiftAll<U>(iter: ESIterable<U>): Stack<T|U>;
      shift(): this;
      push<U>(...values: U[]): Stack<T|U>;
      pushAll<U>(iter: ESIterable<U>): Stack<T|U>;
      pop(): this;
  
      withMutations(mutator: (mutable: this) => any): this;
      asMutable(): this;
      asImmutable(): this;
  
      // Overrides that specialize return types
  
      map<U>(
        mapper: (value: T, index: number, iter: this) => U,
        context?: any
      ): Stack<U>;
  
      flatMap<U>(
        mapper: (value: T, index: number, iter: this) => ESIterable<U>,
        context?: any
      ): Stack<U>;
  
      flatten(depth?: number): /*this*/Stack<any>;
      flatten(shallow?: boolean): /*this*/Stack<any>;
    }
  
    declare function Range(start?: number, end?: number, step?: number): IndexedSeq<number>;
    declare function Repeat<T>(value: T, times?: number): IndexedSeq<T>;
  
    // TODO: Once flow can extend normal Objects we can change this back to actually reflect Record behavior.
    // For now fallback to any to not break existing code
    declare class Record<T: Object> {
      static <T: Object>(spec: T, name?: string): /*T & Record<T>*/any;
      get<A>(key: $Keys<T>): A;
      set<A>(key: $Keys<T>, value: A): /*T & Record<T>*/this;
      remove(key: $Keys<T>): /*T & Record<T>*/this;
    }
  
    declare function fromJS(json: any, reviver?: (k: any, v: Iterable<any,any>) => any): any;
    declare function is(first: any, second: any): boolean;
  
  }
  