 }
 
 fileprivate extension ObservableCollectionChange {
-    fileprivate func unwrap(using list: UnderlyingCollection) -> [ObservableCollectionChange] {
-        func deletionsPatch(_ indices: [UnderlyingCollection.Index]) -> [UnderlyingCollection.Index] {
+    fileprivate func unwrap<C: Collection>(using list: C) -> [ObservableCollectionChange] where C.Index == Index {
+        func deletionsPatch(_ indices: [Index]) -> [Index] {
             var indices = indices
             for i in 0..<indices.count {
                 let pivot = indices[i]

import Differ
import ReactiveKit

public enum ObservableCollectionChange<UnderlyingCollection: Collection>: Equatable {
    case reset
    case inserts([UnderlyingCollection.Index])
    case deletes([UnderlyingCollection.Index])
    case updates([UnderlyingCollection.Index])
    case move(UnderlyingCollection.Index, UnderlyingCollection.Index)
    case beginBatchEditing
    case endBatchEditing
}

public protocol ObservableCollectionEventProtocol {
    associatedtype UnderlyingCollection: Collection & DataSourceProtocol

    var change: ObservableCollectionChange<UnderlyingCollection> { get }
    var source: UnderlyingCollection { get }
}

public struct ObservableCollectionEvent<UnderlyingCollection: Collection & DataSourceProtocol>: ObservableCollectionEventProtocol {
    public let change: ObservableCollectionChange<UnderlyingCollection>
    public let source: UnderlyingCollection

    public init(change: ObservableCollectionChange<UnderlyingCollection>, source: UnderlyingCollection) {
        self.change = change
        self.source = source
    }
}

public struct ObservableCollectionPatchEvent<UnderlyingCollection: Collection & DataSourceProtocol>: ObservableCollectionEventProtocol {
    public let change: ObservableCollectionChange<UnderlyingCollection>
    public let source: UnderlyingCollection

    public init(change: ObservableCollectionChange<UnderlyingCollection>, source: UnderlyingCollection) {
        self.change = change
        self.source = source
    }
}

public class ObservableCollection<UnderlyingCollection: Collection & DataSourceProtocol>: SignalProtocol {
    public fileprivate(set) var collection: UnderlyingCollection
    public let subject = PublishSubject<ObservableCollectionEvent<UnderlyingCollection>, NoError>()
    public let lock = NSRecursiveLock(name: "com.reactivekit.bond.observable-collection")


        // use proxy to collect changes
        let proxy = MutableObservableCollection(collection)
        var patch: [ObservableCollectionChange<UnderlyingCollection.Index>] = []
        let disposable = proxy.skip(first: 1).observeNext { event in
            patch.append(event.change)
        }
