   
   @inlinable
   public var endIndex: Index {
-    Index(lowerBound: base.endIndex, upperBound: base.endIndex)
+    Index(lowerBound: base.endIndex)
   }
   
   @inlinable
   public func index(after i: Index) -> Index {
-    let upperBound = i.upperBound ?? endOfChunk(from: i.lowerBound)
-    let end = endOfChunk(from: upperBound)
+    precondition(i != endIndex, "Can't advance past endIndex")
+    let upperBound = i.upperBound ?? endOfChunk(startingAt: i.lowerBound)
+    guard upperBound != base.endIndex else { return endIndex }
+    let end = endOfChunk(startingAt: upperBound)
     return Index(lowerBound: upperBound, upperBound: end)
   }
   
   @inlinable
   public subscript(position: Index) -> Base.SubSequence {
     let upperBound = position.upperBound
-      ?? endOfChunk(from: position.lowerBound)
+      ?? endOfChunk(startingAt: position.lowerBound)
     return base[position.lowerBound..<upperBound]
   }
 }


  @inlinable
  public func index(before i: Index) -> Index {
    let start = startOfChunk(endingAt: i.lowerBound)
    return Index(lowerBound: start, upperBound: i.lowerBound)
  }

  @inlinable
  public func chunked<Subject: Equatable>(
    on projection: @escaping (Element) -> Subject
  ) -> LazyChunked<Elements, Subject> {
    LazyChunked(
      base: elements,
      projection: projection,
      belongInSameGroup: ==)
  }
}

