/// <summary> /// Performs the specified action on each <see cref="Chord"/> contained in the <see cref="EventsCollection"/>. /// </summary> /// <param name="eventsCollection"><see cref="EventsCollection"/> to search for chords to process.</param> /// <param name="action">The action to perform on each <see cref="Chord"/> contained in the /// <paramref name="eventsCollection"/>.</param> /// <param name="match">The predicate that defines the conditions of the <see cref="Chord"/> to process.</param> /// <param name="notesTolerance">Notes tolerance that defines maximum distance of notes from the /// start of the first note of a chord. Notes within this tolerance will be considered as a chord.</param> /// <exception cref="ArgumentNullException"><paramref name="eventsCollection"/> is null. -or- /// <paramref name="action"/> is null.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="notesTolerance"/> is negative.</exception> public static void ProcessChords(this EventsCollection eventsCollection, Action <Chord> action, Predicate <Chord> match = null, long notesTolerance = 0) { ThrowIfArgument.IsNull(nameof(eventsCollection), eventsCollection); ThrowIfArgument.IsNull(nameof(action), action); ThrowIfNotesTolerance.IsNegative(nameof(notesTolerance), notesTolerance); using (var chordsManager = eventsCollection.ManageChords(notesTolerance)) { foreach (var chord in chordsManager.Chords.Where(c => match?.Invoke(c) != false)) { action(chord); } } }