 @final
 class IndirectArrayBuffer {
   
-  init<T>(nativeBuffer: ContiguousArrayBuffer<T>, isMutable: Bool) {
+  init<T>(
+    nativeBuffer: ContiguousArrayBuffer<T>,
+    isMutable: Bool,
+    needsElementTypeCheck: Bool
+  ) {
     self.buffer = nativeBuffer.storage
     self.isMutable = isMutable
     self.isCocoa = false
-  }
-    
-  init(cocoa: CocoaArray) {
+    self.needsElementTypeCheck = needsElementTypeCheck
+  }
+    
+  init(cocoa: CocoaArray, needsElementTypeCheck: Bool) {
     self.buffer = cocoa
     self.isMutable = false
     self.isCocoa = true
+    self.needsElementTypeCheck = needsElementTypeCheck
   }
 
   init(castFrom: IndirectArrayBuffer, castKind: _ArrayCastKind) {
     self.buffer = castFrom.buffer
-    self.isMutable = castKind == .Down
+    self.isMutable = castKind != .Up
     self.isCocoa = castFrom.isCocoa
+    self.needsElementTypeCheck = castKind == .DeferredDown
   }
   
   // When this buffer has immutable storage and it is modified, the
   // storage is replaced with mutable storage.
-  func replaceStorage<T>(buffer: ContiguousArrayBuffer<T>) {
-    self.buffer = buffer.storage
+  func replaceStorage<T>(newBuffer: ContiguousArrayBuffer<T>) {
+    self.buffer = newBuffer.storage
     self.isMutable = true
     self.isCocoa = false
   }

  /// Get/set the value of the ith element
  subscript(i: Int) -> T {
    get {
      if _fastPath(_isNative) {
        return _native[i]
      }

  /// Return a SliceBuffer containing the given subRange of values
  /// from this buffer.
  subscript(subRange: Range<Int>) -> SliceBuffer<T> {
    _typeCheck(subRange)
    
    if _fastPath(_isNative) {
      return _native[subRange]
