         }
         return capacity - start + i
     }
-}
-
-//MARK: DequeBuffer
-
-class DequeBufferBase: NonObjectiveCBase {
-    private override init() {
-        fatalError("")
-    }
-}
-
-/// Storage buffer for a deque.
-final class DequeBuffer<Element>: DequeBufferBase {
-    private typealias Manager = ManagedBufferPointer<DequeBufferHeader, Element>
-
-    private override init() {
-        fatalError("")
-    }
-
-    @warn_unused_result
-    internal static func create(capacity capacity: Int = 16) -> DequeBuffer<Element> {
-        let manager = Manager(
-            bufferClass: self,
-            minimumCapacity: capacity,
-            initialValue: { buffer, allocatedCount in
-                DequeBufferHeader(capacity: allocatedCount(buffer), count: 0, start: 0)
-            })
-        return unsafeDowncast(manager.buffer)
-    }
-
-    @warn_unused_result
-    internal func realloc(capacity: Int) -> DequeBuffer {
-        if capacity <= self.capacity { return self }
-        let buffer = DequeBuffer.create(capacity: capacity)
-        buffer.count = self.count
-        buffer.manager.withUnsafeMutablePointerToElements { dst in
-            self.manager.withUnsafeMutablePointerToElements { src in
-                let h = self.manager.value
-                if h.start + h.count <= h.capacity {
-                    dst.moveInitializeFrom(src.advancedBy(h.start), count: h.count)
-                }
-                else {
-                    let c = h.capacity - h.start
-                    dst.moveInitializeFrom(src.advancedBy(h.start), count: c)
-                    dst.advancedBy(c).moveInitializeFrom(src, count: h.count - c)
-                }
-            }
-        }
-        self.count = 0
-        return buffer
-    }
-
-    deinit {
-        self.manager.withUnsafeMutablePointers { header, elements in
-            let rest = header.memory.capacity - header.memory.start
-            let count = header.memory.count
-
-            elements.advancedBy(header.memory.start).destroy(min(rest, count))
-            if rest < count {
-                elements.destroy(count - rest)
-            }
-            header.destroy()
-        }
-    }
-
-    private var manager: Manager { return Manager(unsafeBufferObject: self) }
-
-    internal private(set) var count: Int {
-        get { return manager.value.count }
-        set { manager.withUnsafeMutablePointerToValue { $0.memory.count = newValue } }
-    }
-
-    internal var capacity: Int { return manager.value.capacity }
+
     internal var isFull: Bool { return count == capacity }
-
-    internal private(set) var start: Int {
-        get { return manager.value.start }
-        set { manager.withUnsafeMutablePointerToValue { $0.memory.start = newValue } }
-    }
 
     internal subscript(index: Int) -> Element {
         get {
             assert(index >= 0 && index < count)
-            return manager.withUnsafeMutablePointers { hp, p in
-                let i = hp.memory.bufferIndexForDequeIndex(index)
-                return p.advancedBy(i).memory
-            }
+            let i = bufferIndexForDequeIndex(index)
+            return elements.advancedBy(i).memory
         }
         set {
             assert(index >= 0 && index < count)
-            manager.withUnsafeMutablePointers { hp, p in
-                let i = hp.memory.bufferIndexForDequeIndex(index)
-                p.advancedBy(i).memory = newValue
-            }
+            let i = bufferIndexForDequeIndex(index)
+            elements.advancedBy(i).memory = newValue
         }
     }
 
     internal func prepend(element: Element) {
         precondition(count < capacity)
         let i = start == 0 ? capacity - 1 : start - 1
-        manager.withUnsafeMutablePointerToElements { elements in
-            elements.advancedBy(i).initialize(element)
-        }
+        elements.advancedBy(i).initialize(element)
         self.start = i
         self.count += 1
     }
 
     internal func popFirst() -> Element? {
         guard count > 0 else { return nil }
-        let index = self.start
-        let first = manager.withUnsafeMutablePointerToElements { elements in
-            return elements.advancedBy(index).move()
-        }
-        self.start = manager.value.bufferIndexForDequeIndex(1)
+        let first = elements.advancedBy(start).move()
+        self.start = bufferIndexForDequeIndex(1)
         self.count -= 1
         return first
     }
 
     internal func append(element: Element) {
         precondition(count < capacity)
-        let i = manager.value.bufferIndexForDequeIndex(count)
-        manager.withUnsafeMutablePointerToElements { elements in
-            elements.advancedBy(i).initialize(element)
-        }
+        let endIndex = bufferIndexForDequeIndex(count)
+        elements.advancedBy(endIndex).initialize(element)
         self.count += 1
     }
 
     internal func popLast() -> Element? {
         guard count > 0 else { return nil }
-        let index = manager.value.bufferIndexForDequeIndex(count - 1)
-        let last = manager.withUnsafeMutablePointerToElements { elements in
-            return elements.advancedBy(index).move()
-        }
+        let lastIndex = bufferIndexForDequeIndex(count - 1)
+        let last = elements.advancedBy(lastIndex).move()
         self.count -= 1
         return last
     }


    private mutating func makeUniqueWithCapacity(capacity: Int) {
        guard !isUnique || buffer.capacity < capacity else { return }
        let copy = DequeBuffer<Element>.create(capacity: capacity)
        copy.insertContentsOf(buffer, at: 0)
        buffer = copy
    }

    /// Destroy elements in the range (index ..< index + count) and collapse the gap by moving remaining elements.
    /// Note that all previously calculated buffer indexes are invalidated by this method.
    private func removeRange(range: Range<Int>) {
        assert(range.startIndex >= 0)
        assert(range.endIndex <= self.count)
        guard range.count > 0 else { return }
        let rc = range.count
        let p = elements
        let i = bufferIndexForDequeIndex(range.startIndex)
        let j = i + rc <= capacity ? i + rc : i + rc - capacity

        // Destroy items in collapsed range
        if i <= j {
            // ....ABC̲D̲E̲FG...
            p.advancedBy(i).destroy(rc)
            // ....AB...FG...
        }
        else {
            // D̲E̲FG.......ABC̲
            p.advancedBy(i).destroy(capacity - i)
            // D̲E̲FG.......AB.
            p.destroy(j)
            // ..FG.......AB.
        }

        if count - range.startIndex - rc < range.startIndex {
            let end = start + count < capacity ? start + count : start + count - capacity

            // Slide trailing items to the left
            if i <= end { // No wrap anywhere after start of collapsed range
                // ....AB.̲..CD...
                p.advancedBy(i).moveInitializeFrom(p.advancedBy(i + rc), count: end - i - rc)
                // ....ABC̲D......
            }
            else if i + rc > capacity { // Collapsed range is wrapped
                if end <= rc { // Result will not be wrapped
                    // .CD......AB.̲..
                    p.advancedBy(i).moveInitializeFrom(p.advancedBy(i + rc - capacity), count: capacity + end - i - rc)
                    // .........ABC̲D.
                }
                else { // Result will remain wrapped
                    // .CDEFG...AB.̲..
                    p.advancedBy(i).moveInitializeFrom(p.advancedBy(i + rc - capacity), count: capacity - i)
                    // ....FG...ABC̲DE
                    p.moveInitializeFrom(p.advancedBy(rc), count: end - rc)
                    // FG.......ABC̲DE
                }
            }
            else { // Wrap is after collapsed range
                if end <= rc { // Result will not be wrapped
                    // D.......AB.̲..C
                    p.advancedBy(i).moveInitializeFrom(p.advancedBy(i + rc), count: capacity - i - rc)
                    // D.......ABC̲...
                    p.advancedBy(capacity - rc).moveInitializeFrom(p, count: end)
                    // ........ABC̲D..
                }
                else { // Result will remain wrapped
                    // DEFG....AB.̲..C
                    p.advancedBy(i).moveInitializeFrom(p.advancedBy(i + rc), count: capacity - i - rc)
                    // DEFG....ABC̲...
                    p.advancedBy(capacity - rc).moveInitializeFrom(p, count: rc)
                    // ...G....ABC̲DEF
                    p.moveInitializeFrom(p.advancedBy(rc), count: end - rc)
                    // G.......ABC̲DEF
                }
            }
            count -= rc
        }
        else {
            // Slide preceding items to the right
            if j >= start { // No wrap anywhere before end of collapsed range
                // ...AB...C̲D...
                p.advancedBy(start + rc).moveInitializeBackwardFrom(p.advancedBy(start), count: j - start - rc)
                // ......ABC̲D...
            }
            else if j < rc { // Collapsed range is wrapped
                if  start + rc >= capacity  { // Result will not be wrapped
                    // ...C̲D.....AB..
                    p.advancedBy(start + rc - capacity).moveInitializeFrom(p.advancedBy(start), count: capacity + j - start - rc)
                    // .ABC̲D.........
                }
                else { // Result will remain wrapped
                    // ..E̲F.....ABCD..
                    p.moveInitializeFrom(p.advancedBy(capacity - rc), count: j)
                    // CDE̲F.....AB....
                    p.advancedBy(start + rc).moveInitializeBackwardFrom(p.advancedBy(start), count: capacity - start - rc)
                    // CDE̲F.........AB
                }
            }
            else { // Wrap is before collapsed range
                if capacity - start <= rc { // Result will not be wrapped
                    // CD...E̲F.....AB
                    p.advancedBy(rc).moveInitializeBackwardFrom(p, count: j - rc)
                    // ...CDE̲F.....AB
                    p.advancedBy(start + rc - capacity).moveInitializeFrom(p.advancedBy(start), count: capacity - start)
                    // .ABCDE̲F.......
                }
                else { // Result will remain wrapped
                    // EF...G̲H...ABCD
                    p.advancedBy(rc).moveInitializeBackwardFrom(p, count: j - rc)
                    // ...EFG̲H...ABCD
                    p.moveInitializeFrom(p.advancedBy(capacity) - rc, count: rc)
                    // BCDEFG̲H...A...
                    p.advancedBy(start + rc).moveInitializeBackwardFrom(p.advancedBy(start), count: capacity - start - rc)
                    // BCDEFG̲H......A
                }
            }
            start = (start + rc < capacity ? start + rc : start + rc - capacity)
            count -= rc
        }
    }

    internal func replaceRange<C: CollectionType where C.Generator.Element == Element>(range: Range<Int>, with newElements: C) {
        let newCount: Int = numericCast(newElements.count)
        let delta = newCount - range.count
        assert(count + delta < capacity)
        let common = min(range.count, newCount)
        if common > 0 {
            let p = elements
            var q = p.advancedBy(bufferIndexForDequeIndex(range.startIndex))
            let limit = p.advancedBy(capacity)
            var i = common
            for element in newElements {
                q.memory = element
                q = q.successor()
                if q == limit { q = p }
                i -= 1
                if i == 0 { break }
            }
        }
        if range.count > common {
            removeRange(range.startIndex + common ..< range.endIndex)
        }
        else if newCount > common {
            openGapAt(range.startIndex + common, length: newCount - common)
            let p = elements
            var q = p.advancedBy(bufferIndexForDequeIndex(range.startIndex + common))
            let limit = p.advancedBy(capacity)
            var i = newElements.startIndex.advancedBy(numericCast(common))
            while i != newElements.endIndex {
                q.initialize(newElements[i])
                i = i.successor()
                q = q.successor()
                if q == limit { q = p }
            }
        }
    }
}
