         recomputeNoteCollectionIndexes()
     }
 
+    /**
+     Gets note stored at `index`.
+     
+     - parameter index: The index of the note in the specified note set.
+     - parameter setIndex: Note set index.
+     - throws:
+        - `TupletError.invalidIndex`
+        - `TupletError.internalError`
+        - `MeasureError.noteIndexOutOfRange`
+     */
     public func note(at index: Int, inSet setIndex: Int = 0) throws -> Note {
         let collectionIndex = try noteCollectionIndex(fromNoteIndex: index, inSet: setIndex)
         let noteIndex = collectionIndex.tupletIndex ?? 0
         return try notes[setIndex][collectionIndex.noteIndex].note(at: noteIndex)
     }
 
-    public mutating func replaceNote<T: NoteCollection>(at index: Int, with noteCollection: T, inSet setIndex: Int = 0) throws {
-        var newMeasure = self
-        let noteCollections = try newMeasure.prepTiesForReplacement(in: index...index, with: [noteCollection], inSet: setIndex)
-        let collectionIndex = try newMeasure.noteCollectionIndex(fromNoteIndex: index, inSet: setIndex)
-        try newMeasure.replaceNote(at: collectionIndex, with: noteCollections, inSet: setIndex)
-        self = newMeasure
-    }
-
-    public mutating func replaceNote<T: NoteCollection>(at index: Int, with noteCollections: [T], inSet setIndex: Int = 0) throws {
+    /**
+     Replaces note at `index` in `setIndex` with `noteCollection`.
+     
+     The `Tie` state of the note being replaced is preserved in `noteCollection`.
+
+     - parameter index: The index of the note in the specified note set.
+     - parameter noteCollection: `NoteCollection` used in note replacement.
+     - parameter setIndex: Note set index.
+     - throws:
+        - `MeasureError.noteIndexOutOfRange`
+        - `MeasureError.internalError`
+
+     */
+    public mutating func replaceNote(at index: Int, with noteCollection: NoteCollection, inSet setIndex: Int = 0) throws {
+        try replaceNote(at: index, with: [noteCollection], inSet: setIndex)
+    }
+
+    /**
+     Replaces note at `index` in `setIndex` with `noteCollections` array.
+     
+     The `Tie` state of the note being replaced is preserved in the `noteCollections` array.
+     
+     - parameter index: The index of the note in the specified note set.
+     - parameter noteCollections: `NoteCollection` array used in note replacement.
+     - parameter setIndex: Note set index.
+     - throws:
+        - `MeasureError.invalidNoteCollection` If `noteCollections` is empty.
+        - `MeasureError.noteIndexOutOfRange`
+        - `MeasureError.internalError`
+     */
+    public mutating func replaceNote(at index: Int, with noteCollections: [NoteCollection], inSet setIndex: Int = 0) throws {
         var newMeasure = self
         let noteCollections = try newMeasure.prepTiesForReplacement(in: index...index, with: noteCollections, inSet: setIndex)
         let collectionIndex = try newMeasure.noteCollectionIndex(fromNoteIndex: index, inSet: setIndex)

        self = newMeasure
    }

    public mutating func breakdownTuplet(at index: Int, inSet setIndex: Int = 0) throws {
        var newMeasure = self
        let collectionIndex = try newMeasure.noteCollectionIndex(fromNoteIndex: index, inSet: setIndex)

        self = newMeasure
    }

    /**
     Remove notes in range.
     
     - parameter indexRange:
     - parameter setIndex:
     - parameter skipTieConfig:
     - throws:
        - `MeasureError.internalError`
        - `MeasureError.incompleteTuplet`
        - `MeasureError.invalidTieState`
     */
    internal mutating func removeNotesInRange(_ indexRange: CountableClosedRange<Int>, inSet setIndex: Int = 0, skipTies skipTieConfig: Bool) throws {
        var newMeasure = self

