   }
 
   /// Map each event into a signal and then flatten inner signals.
+  public func flatMap<O: SignalProtocol>(_ strategy: FlattenStrategy, _ transform: @escaping (Element) -> O) -> Signal<O.Element, O.Error> {
+    return castError().map(transform).flatten(strategy)
+  }
+
+  /// Map each event into a signal and then flatten inner signals.
   public func flatMapLatest<O: SignalProtocol>(_ transform: @escaping (Element) -> O) -> Signal<O.Element, O.Error> {
-    return castError().map(transform).switchToLatest()
+    return flatMap(.latest, transform)
   }
 
   /// Map each event into a signal and then flatten inner signals.
   public func flatMapMerge<O: SignalProtocol>(_ transform: @escaping (Element) -> O) -> Signal<O.Element, O.Error> {
-    return castError().map(transform).merge()
+    return flatMap(.merge, transform)
   }
 
   /// Map each event into a signal and then flatten inner signals.
   public func flatMapConcat<O: SignalProtocol>(_ transform: @escaping (Element) -> O) -> Signal<O.Element, O.Error>  {
-    return castError().map(transform).concat()
+    return flatMap(.concat, transform)
   }
 
   /// Transform each element by applying `transform` on it.

  }

  /// Map each event into a signal and then flatten inner signals.
  public func flatMapLatest<O: SignalProtocol>(_ transform: @escaping (Element) -> O) -> Signal<O.Element, Error> where O.Error == Error {
    return map(transform).switchToLatest()
  }

  /// Map each event into a signal and then flatten inner signals.
  public func flatMapMerge<O: SignalProtocol>(_ transform: @escaping (Element) -> O) -> Signal<O.Element, Error> where O.Error == Error {
    return map(transform).merge()
  }

  /// Map each event into a signal and then flatten inner signals.
  public func flatMapConcat<O: SignalProtocol>(_ transform: @escaping (Element) -> O) -> Signal<O.Element, Error> where O.Error == Error {
    return map(transform).concat()
  }

  /// Map failure event into another operation and continue with that operation. Also called `catch`.


extension SignalProtocol where Element: Sequence {

  @available(*, deprecated, renamed: "mapElement(_:)")
  public func flatMap<U>(_ transform: @escaping (Element.Iterator.Element) -> U) -> Signal<[U], Error> {
    return mapElement(transform)
  }

  /// Map each emitted sequence.
  public func mapElement<U>(_ transform: @escaping (Element.Iterator.Element) -> U) -> Signal<[U], Error> {
    return Signal { observer in
      return self.observe { event in
        switch event {
