diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateBy/AggregateBy1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateBy/AggregateBy1.linq
new file mode 100644
index 000000000..979f80d34
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateBy/AggregateBy1.linq
@@ -0,0 +1,21 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 19);
+
+// Aggregate elements in a sequence grouped by key
+var result = sequence
+ .AggregateBy(
+ x => x % 3,
+ 0,
+ (acc, e) => acc + e);
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [[1, 70], [2, 57], [0, 63]]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateBy/AggregateBy2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateBy/AggregateBy2.linq
new file mode 100644
index 000000000..9bc4edaf8
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateBy/AggregateBy2.linq
@@ -0,0 +1,21 @@
+
+ C:\Users\stuar\source\repos\viceroypenguin\SuperLinq\Source\SuperLinq\bin\Release\net7.0\SuperLinq.dll
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 19);
+
+// Aggregate elements in a sequence grouped by key
+var result = sequence
+ .AggregateBy(
+ x => x % 3,
+ k => k * 1_000,
+ (acc, e) => acc + e);
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [[1, 1070], [2, 2057], [0, 63]]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateRight/AggregateRight1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateRight/AggregateRight1.linq
new file mode 100644
index 000000000..c78c98b6e
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateRight/AggregateRight1.linq
@@ -0,0 +1,15 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var numbers = new string[] { "1", "2", "3", "4", "5", };
+
+// Enumerate strings from right to left and collect the text into larger strings.
+var result = numbers
+ .AggregateRight((a, b) => $"({a}/{b})");
+
+Console.WriteLine(result);
+
+// This code produces the following output:
+// (1/(2/(3/(4/5))))
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateRight/AggregateRight2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateRight/AggregateRight2.linq
new file mode 100644
index 000000000..0fed4aa26
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateRight/AggregateRight2.linq
@@ -0,0 +1,15 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var numbers = new string[] { "1", "2", "3", "4", "5", };
+
+// Enumerate strings from right to left and collect the text into larger strings.
+var result = numbers
+ .AggregateRight("6", (a, b) => $"({a}/{b})");
+
+Console.WriteLine(result);
+
+// This code produces the following output:
+// (1/(2/(3/(4/(5/6)))))
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateRight/AggregateRight3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateRight/AggregateRight3.linq
new file mode 100644
index 000000000..93123483c
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AggregateRight/AggregateRight3.linq
@@ -0,0 +1,18 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var numbers = new string[] { "1", "2", "3", "4", "5", };
+
+// Enumerate strings from right to left and collect the text into larger strings.
+var result = numbers
+ .AggregateRight(
+ "6",
+ (a, b) => $"({a}/{b})",
+ s => s.Length);
+
+Console.WriteLine(result);
+
+// This code produces the following output:
+// 21
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/AssertCount/AssertCount.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AssertCount/AssertCount.linq
new file mode 100644
index 000000000..03b5bfc3e
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AssertCount/AssertCount.linq
@@ -0,0 +1,28 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var numbers = new string[] { "1", "2", "3", "4", "5", };
+
+// Enumerate the sequence with a valid length.
+// This code executes normally.
+numbers
+ .AssertCount(5)
+ .Consume();
+
+// Enumerate the sequence with an invalid length.
+// This code throws an `ArgumentException`
+try
+{
+ numbers
+ .AssertCount(4)
+ .Consume();
+}
+catch (ArgumentException ae)
+{
+ Console.WriteLine(ae.Message);
+
+ // This code produces the following output:
+ // Parameter "source.Count()" (int) must be equal to <4>, was <5>. (Parameter 'source.Count()')
+}
\ No newline at end of file
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/AtLeast/AtLeast.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AtLeast/AtLeast.linq
new file mode 100644
index 000000000..a7f4479a7
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AtLeast/AtLeast.linq
@@ -0,0 +1,21 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 5);
+
+foreach (var x in Enumerable.Range(3, 5))
+{
+ // Check that a sequence has a minimum size
+ var result = sequence.AtLeast(x);
+
+ Console.WriteLine($"AtLeast {x}: {result}");
+}
+
+// This code produces the following output:
+// AtLeast 3: True
+// AtLeast 4: True
+// AtLeast 5: True
+// AtLeast 6: False
+// AtLeast 7: False
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/AtMost/AtMost.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AtMost/AtMost.linq
new file mode 100644
index 000000000..5994e7929
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/AtMost/AtMost.linq
@@ -0,0 +1,21 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 5);
+
+foreach (var x in Enumerable.Range(3, 5))
+{
+ // Check that a sequence has a maximum length
+ var result = sequence.AtMost(x);
+
+ Console.WriteLine($"AtMost {x}: {result}");
+}
+
+// This code produces the following output:
+// AtMost 3: False
+// AtMost 4: False
+// AtMost 5: True
+// AtMost 6: True
+// AtMost 7: True
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Backsert/Backsert.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Backsert/Backsert.linq
new file mode 100644
index 000000000..ed3ec49a2
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Backsert/Backsert.linq
@@ -0,0 +1,16 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var first = Enumerable.Range(1, 5);
+var second = Enumerable.Range(1, 5);
+
+// Insert one sequence into another
+var result = first
+ .Backsert(second, 2);
+
+Console.WriteLine(string.Join(", ", result));
+
+// This code produces the following output:
+// 1, 2, 3, 1, 2, 3, 4, 5, 4, 5
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Batch/Batch1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Batch/Batch1.linq
new file mode 100644
index 000000000..e421cba03
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Batch/Batch1.linq
@@ -0,0 +1,19 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 10);
+
+// Break the sequence of numbers into three chunks of 3 and one chunk of 1
+var result = sequence.Batch(3);
+
+Console.WriteLine(
+ "[" +
+ string.Join(
+ ", ",
+ result.Select(c => "[" + string.Join(", ", c) + "]")) +
+ "]");
+
+// This code produces the following output:
+// [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Batch/Batch2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Batch/Batch2.linq
new file mode 100644
index 000000000..ec1a4dec9
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Batch/Batch2.linq
@@ -0,0 +1,20 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 10);
+
+// Break the sequence of numbers into three chunks of 3 and one chunk of 1
+var result = sequence
+ .Batch(
+ 3,
+ c => "[" + string.Join(", ", c) + "]");
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Batch/Batch3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Batch/Batch3.linq
new file mode 100644
index 000000000..b0d931d1a
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Batch/Batch3.linq
@@ -0,0 +1,21 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 10);
+
+// Break the sequence of numbers into three chunks of 3 and one chunk of 1
+var buffer = new int[3];
+var result = sequence
+ .Batch(
+ buffer,
+ c => "[" + string.Join(", ", c) + "]");
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Batch/Batch4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Batch/Batch4.linq
new file mode 100644
index 000000000..4af1780ce
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Batch/Batch4.linq
@@ -0,0 +1,22 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 10);
+
+// Break the sequence of numbers into three chunks of 3 and one chunk of 1
+var buffer = new int[5];
+var result = sequence
+ .Batch(
+ buffer,
+ 3,
+ c => "[" + string.Join(", ", c) + "]");
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/BindByIndex/BindByIndex1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/BindByIndex/BindByIndex1.linq
new file mode 100644
index 000000000..80425e0b8
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/BindByIndex/BindByIndex1.linq
@@ -0,0 +1,19 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 10);
+var indices = new int[] { 0, 1, 8, 9, 3, 4, 2, };
+
+// Select elements from sequence using the values in indices
+var result = sequence
+ .BindByIndex(indices);
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [1, 2, 9, 10, 4, 5, 3]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/BindByIndex/BindByIndex2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/BindByIndex/BindByIndex2.linq
new file mode 100644
index 000000000..e8e477fd9
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/BindByIndex/BindByIndex2.linq
@@ -0,0 +1,22 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 10);
+var indices = new int[] { 0, 1, 8, 10, 3, 4, 2, };
+
+// Select elements from sequence using the values in indices
+var result = sequence
+ .BindByIndex(
+ indices,
+ (e, i) => e.ToString(),
+ i => "null");
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [1, 2, 9, null, 4, 5, 3]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Buffer/Buffer1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Buffer/Buffer1.linq
new file mode 100644
index 000000000..130c72f2c
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Buffer/Buffer1.linq
@@ -0,0 +1,19 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 10);
+
+// Break the sequence of numbers into three chunks of 3 and one chunk of 1
+var result = sequence.Buffer(3);
+
+Console.WriteLine(
+ "[" +
+ string.Join(
+ ", ",
+ result.Select(c => "[" + string.Join(", ", c) + "]")) +
+ "]");
+
+// This code produces the following output:
+// [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Buffer/Buffer2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Buffer/Buffer2.linq
new file mode 100644
index 000000000..b408ae632
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Buffer/Buffer2.linq
@@ -0,0 +1,19 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 10);
+
+// Break the sequence of numbers into overlapping chunks of size 3
+var result = sequence.Buffer(3, 2);
+
+Console.WriteLine(
+ "[" +
+ string.Join(
+ ", ",
+ result.Select(c => "[" + string.Join(", ", c) + "]")) +
+ "]");
+
+// This code produces the following output:
+// [[1, 2, 3], [3, 4, 5], [5, 6, 7], [7, 8, 9], [9, 10]]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Cartesian/Cartesian.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Cartesian/Cartesian.linq
new file mode 100644
index 000000000..c59aee9b1
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Cartesian/Cartesian.linq
@@ -0,0 +1,18 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var seq1 = new[] { 1, 2, 3, };
+var seq2 = new[] { "foo", "bar", "quz", };
+
+// Take a slice of the sequence
+var result = seq1.Cartesian(seq2);
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [(1, foo), (1, bar), (1, quz), (2, foo), (2, bar), (2, quz), (3, foo), (3, bar), (3, quz)]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Case/Case1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Case/Case1.linq
new file mode 100644
index 000000000..0f33f799c
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Case/Case1.linq
@@ -0,0 +1,27 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequences = Enumerable.Range(1, 5)
+ .ToDictionary(
+ x => x,
+ x => Enumerable.Range(1, x));
+
+// Use a function to select which sequence to return values from.
+var selector = 1;
+var result = SuperEnumerable
+ .Case(
+ () => selector,
+ sequences);
+
+Console.WriteLine($"Selector: {selector}; result.Count(): {result.Count()}.");
+selector = 4;
+Console.WriteLine($"Selector: {selector}; result.Count(): {result.Count()}.");
+selector = 2;
+Console.WriteLine($"Selector: {selector}; result.Count(): {result.Count()}.");
+
+// This code produces the following output:
+// Selector: 1; result.Count(): 1.
+// Selector: 4; result.Count(): 4.
+// Selector: 2; result.Count(): 2.
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Case/Case2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Case/Case2.linq
new file mode 100644
index 000000000..2625800bb
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Case/Case2.linq
@@ -0,0 +1,28 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequences = Enumerable.Range(1, 5)
+ .ToDictionary(
+ x => x,
+ x => Enumerable.Range(1, x));
+
+// Use a function to select which sequence to return values from.
+var selector = 1;
+var result = SuperEnumerable
+ .Case(
+ () => selector,
+ sequences,
+ Enumerable.Range(1, 100));
+
+Console.WriteLine($"Selector: {selector}; result.Count(): {result.Count()}.");
+selector = 4;
+Console.WriteLine($"Selector: {selector}; result.Count(): {result.Count()}.");
+selector = 20;
+Console.WriteLine($"Selector: {selector}; result.Count(): {result.Count()}.");
+
+// This code produces the following output:
+// Selector: 1; result.Count(): 1.
+// Selector: 4; result.Count(): 4.
+// Selector: 20; result.Count(): 100.
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Catch/Catch1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Catch/Catch1.linq
new file mode 100644
index 000000000..d1400737b
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Catch/Catch1.linq
@@ -0,0 +1,21 @@
+
+ SuperLinq
+ SuperLinq
+
+
+// this sequence will throw an exception on the 6th element
+var sequence = Enumerable.Range(1, 5).Select(i => i.ToString())
+ .Concat(SuperEnumerable.Throw(new InvalidOperationException()));
+
+// Use a function to determine how to handle an exception
+var result = sequence
+ .Catch(
+ (InvalidOperationException ex) => SuperEnumerable.Return(ex.Message));
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [1, 2, 3, 4, 5, Operation is not valid due to the current state of the object.]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Catch/Catch2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Catch/Catch2.linq
new file mode 100644
index 000000000..49515a782
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Catch/Catch2.linq
@@ -0,0 +1,20 @@
+
+ SuperLinq
+ SuperLinq
+
+
+// this sequence will throw an exception on the 6th element
+var sequence = Enumerable.Range(1, 5)
+ .Concat(SuperEnumerable.Throw(new InvalidOperationException()));
+
+// Use a second sequence to continue in the case of an exception
+var result = sequence
+ .Catch(Enumerable.Range(1, 5));
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Catch/Catch3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Catch/Catch3.linq
new file mode 100644
index 000000000..bef0bdb91
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Catch/Catch3.linq
@@ -0,0 +1,24 @@
+
+ SuperLinq
+ SuperLinq
+
+
+// this sequence will throw an exception on the 6th element
+var sequence = Enumerable.Range(1, 5)
+ .Concat(SuperEnumerable.Throw(new InvalidOperationException()));
+
+// Use a series of sequences to enumerate until one completes successfully.
+var result = SuperEnumerable
+ .Catch(
+ sequence,
+ sequence,
+ Enumerable.Range(1, 3),
+ Enumerable.Range(1, 10));
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Catch/Catch4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Catch/Catch4.linq
new file mode 100644
index 000000000..6286b7c6b
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Catch/Catch4.linq
@@ -0,0 +1,27 @@
+
+ SuperLinq
+ SuperLinq
+
+
+// this sequence will throw an exception on the 6th element
+var sequence = Enumerable.Range(1, 5)
+ .Concat(SuperEnumerable.Throw(new InvalidOperationException()));
+
+// Use a series of sequences to enumerate until one completes successfully.
+var result = SuperEnumerable
+ .Catch(
+ new List>
+ {
+ sequence,
+ sequence,
+ Enumerable.Range(1, 3),
+ Enumerable.Range(1, 10),
+ });
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Choose/Choose.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Choose/Choose.linq
new file mode 100644
index 000000000..99d489fb0
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Choose/Choose.linq
@@ -0,0 +1,18 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = "O,l,2,3,4,S,6,7,B,9".Split(',');
+
+// Use a function to choose and project elements in the sequence
+var result = sequence
+ .Choose(s => (int.TryParse(s, out var n), n));
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [2, 3, 4, 6, 7, 9]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/CollectionEqual/CollectionEqual1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CollectionEqual/CollectionEqual1.linq
new file mode 100644
index 000000000..b4e6127d0
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CollectionEqual/CollectionEqual1.linq
@@ -0,0 +1,17 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var pets1 = new List { new("Turbo", 2), new("Peanut", 8), };
+var pets2 = new List { new("Peanut", 8), new("Turbo", 2), };
+
+// Determine if the two collections are equal, using the default equality comparer
+var result = pets1.CollectionEqual(pets2);
+
+Console.WriteLine(result);
+
+// This code produces the following output:
+// True
+
+record Pet(string Name, int Age);
\ No newline at end of file
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/CollectionEqual/CollectionEqual2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CollectionEqual/CollectionEqual2.linq
new file mode 100644
index 000000000..cbee8e3a7
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CollectionEqual/CollectionEqual2.linq
@@ -0,0 +1,39 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var pets1 = new List { new("Turbo", 2), new("Peanut", 8), };
+var pets2 = new List { new("Peanut", 8), new("Turbo", 2), };
+
+// Determine if the two collections are equal, using a custom equality comparer
+var result = pets1
+ .CollectionEqual(
+ pets2,
+ new PetComparer());
+
+Console.WriteLine(result);
+
+// This code produces the following output:
+// True
+
+class Pet
+{
+ public Pet(string name, int age)
+ {
+ this.Name = name;
+ this.Age = age;
+ }
+
+ public string Name { get; }
+ public int Age { get; }
+}
+
+class PetComparer : IEqualityComparer
+{
+ public bool Equals(Pet x, Pet y) =>
+ x.Name == y.Name
+ && x.Age == y.Age;
+ public int GetHashCode(Pet x) =>
+ HashCode.Combine(x.Name, x.Age);
+}
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/CompareCount/CompareCount.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CompareCount/CompareCount.linq
new file mode 100644
index 000000000..67b716bb9
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CompareCount/CompareCount.linq
@@ -0,0 +1,21 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 5);
+
+foreach (var x in Enumerable.Range(3, 5))
+{
+ // Compare the length of two sequences
+ var result = sequence.CompareCount(Enumerable.Range(1, x));
+
+ Console.WriteLine($"CompareCount {x}: {result}");
+}
+
+// This code produces the following output:
+// CompareCount 3: 1
+// CompareCount 4: 1
+// CompareCount 5: 0
+// CompareCount 6: -1
+// CompareCount 7: -1
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Consume/Consume.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Consume/Consume.linq
new file mode 100644
index 000000000..000797f0d
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Consume/Consume.linq
@@ -0,0 +1,13 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 5)
+ .Do(i => Console.Write($"{i}, "));
+
+// Consume the provided sequence
+sequence.Consume();
+
+// This code produces the following output:
+// 1, 2, 3, 4, 5,
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/CopyTo/CopyTo1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CopyTo/CopyTo1.linq
new file mode 100644
index 000000000..135457283
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CopyTo/CopyTo1.linq
@@ -0,0 +1,20 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 5);
+var destination = new List() { -1, -2, };
+
+// Copy the provided sequence to a list
+var result = sequence.CopyTo(destination);
+
+Console.WriteLine(result);
+Console.WriteLine(
+ "[" +
+ string.Join(", ", destination) +
+ "]");
+
+// This code produces the following output:
+// 5
+// [1, 2, 3, 4, 5]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/CopyTo/CopyTo2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CopyTo/CopyTo2.linq
new file mode 100644
index 000000000..c5d7f020b
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CopyTo/CopyTo2.linq
@@ -0,0 +1,20 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 5);
+var destination = new List() { -1, -2, };
+
+// Copy the provided sequence to a list at a specified index
+var result = sequence.CopyTo(destination, 2);
+
+Console.WriteLine(result);
+Console.WriteLine(
+ "[" +
+ string.Join(", ", destination) +
+ "]");
+
+// This code produces the following output:
+// 5
+// [-1, -2, 1, 2, 3, 4, 5]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/CopyTo/CopyTo3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CopyTo/CopyTo3.linq
new file mode 100644
index 000000000..14e6763aa
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CopyTo/CopyTo3.linq
@@ -0,0 +1,21 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 5);
+var destination = new int[7];
+var span = destination.AsSpan();
+
+// Copy the provided sequence to a span
+var result = sequence.CopyTo(span[1..]);
+
+Console.WriteLine(result);
+Console.WriteLine(
+ "[" +
+ string.Join(", ", destination) +
+ "]");
+
+// This code produces the following output:
+// 5
+// [0, 1, 2, 3, 4, 5, 0]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/CopyTo/CopyTo4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CopyTo/CopyTo4.linq
new file mode 100644
index 000000000..dec6f199d
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CopyTo/CopyTo4.linq
@@ -0,0 +1,20 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 5);
+var destination = new int[5];
+
+// Copy the provided sequence to an array
+var result = sequence.CopyTo(destination);
+
+Console.WriteLine(result);
+Console.WriteLine(
+ "[" +
+ string.Join(", ", destination) +
+ "]");
+
+// This code produces the following output:
+// 5
+// [1, 2, 3, 4, 5]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/CountBetween/CountBetween.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CountBetween/CountBetween.linq
new file mode 100644
index 000000000..991a1b402
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CountBetween/CountBetween.linq
@@ -0,0 +1,21 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 5);
+
+foreach (var x in Enumerable.Range(3, 5))
+{
+ // Check that a sequence has a length between two numbers
+ var result = sequence.CountBetween(x, x + 1);
+
+ Console.WriteLine($"CountBetween {x}-{x + 1}: {result}");
+}
+
+// This code produces the following output:
+// CountBetween 3-4: False
+// CountBetween 4-5: True
+// CountBetween 5-6: True
+// CountBetween 6-7: False
+// CountBetween 7-8: False
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/CountBy/CountBy1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CountBy/CountBy1.linq
new file mode 100644
index 000000000..9f966e198
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CountBy/CountBy1.linq
@@ -0,0 +1,17 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 19);
+
+// Count elements in a sequence grouped by key
+var result = sequence.CountBy(x => x % 3);
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [(1, 7), (2, 6), (0, 6)]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/CountBy/CountBy2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CountBy/CountBy2.linq
new file mode 100644
index 000000000..939337a3b
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CountBy/CountBy2.linq
@@ -0,0 +1,17 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = new[] { "a", "B", "c", "A", "b", "A", };
+
+// Count elements in a sequence grouped by key
+var result = sequence.CountBy(SuperEnumerable.Identity, StringComparer.OrdinalIgnoreCase);
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [(a, 3), (B, 2), (c, 1)]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/CountDown/CountDown1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CountDown/CountDown1.linq
new file mode 100644
index 000000000..c01bc2334
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CountDown/CountDown1.linq
@@ -0,0 +1,17 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 5);
+
+// Get a countdown counter for the the sequence
+var result = sequence.CountDown(2);
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [(1, ), (2, ), (3, ), (4, 1), (5, 0)]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/CountDown/CountDown2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CountDown/CountDown2.linq
new file mode 100644
index 000000000..f958eb167
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/CountDown/CountDown2.linq
@@ -0,0 +1,17 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 5);
+
+// Get a countdown counter for the the sequence
+var result = sequence.CountDown(2, (item, cd) => new { Item = item, CountDown = cd?.ToString() ?? "null", });
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [{ Item = 1, CountDown = null }, { Item = 2, CountDown = null }, { Item = 3, CountDown = null }, { Item = 4, CountDown = 1 }, { Item = 5, CountDown = 0 }]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Defer/Defer.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Defer/Defer.linq
new file mode 100644
index 000000000..7ac256e0e
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Defer/Defer.linq
@@ -0,0 +1,28 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var count = 3;
+
+// Use a function to create a sequence at execution time
+var result = SuperEnumerable
+ .Defer(() => Enumerable.Range(1, count));
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// changing count changes the length of the sequence
+// returned by the function given to Defer
+count = 5;
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [1, 2, 3]
+// [1, 2, 3, 4, 5]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSort/DensePartialSort1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSort/DensePartialSort1.linq
new file mode 100644
index 000000000..1b6d5e70b
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSort/DensePartialSort1.linq
@@ -0,0 +1,47 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = new Item[]
+{
+ new(key: 5, text: "1"),
+ new(key: 5, text: "2"),
+ new(key: 4, text: "3"),
+ new(key: 4, text: "4"),
+ new(key: 3, text: "5"),
+ new(key: 3, text: "6"),
+ new(key: 2, text: "7"),
+ new(key: 2, text: "8"),
+ new(key: 1, text: "9"),
+ new(key: 1, text: "10"),
+};
+
+// Get the top N sets of items
+var result = sequence.DensePartialSort(3);
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [(1, 9), (1, 10), (2, 7), (2, 8), (3, 5), (3, 6)]
+
+class Item : IComparable-
+{
+ public Item(int key, string text)
+ {
+ Key = key;
+ Text = text;
+ }
+
+ public int Key { get; }
+ public string Text { get; }
+
+ public int CompareTo(Item other) =>
+ this.Key.CompareTo(other.Key);
+
+ public override string ToString() =>
+ $"({this.Key}, {this.Text})";
+}
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSort/DensePartialSort2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSort/DensePartialSort2.linq
new file mode 100644
index 000000000..29d89d5de
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSort/DensePartialSort2.linq
@@ -0,0 +1,47 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = new Item[]
+{
+ new(key: 5, text: "1"),
+ new(key: 5, text: "2"),
+ new(key: 4, text: "3"),
+ new(key: 4, text: "4"),
+ new(key: 3, text: "5"),
+ new(key: 3, text: "6"),
+ new(key: 2, text: "7"),
+ new(key: 2, text: "8"),
+ new(key: 1, text: "9"),
+ new(key: 1, text: "10"),
+};
+
+// Get the top N sets of items
+var result = sequence.DensePartialSort(3, OrderByDirection.Descending);
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [(5, 1), (5, 2), (4, 3), (4, 4), (3, 5), (3, 6)]
+
+class Item : IComparable
-
+{
+ public Item(int key, string text)
+ {
+ Key = key;
+ Text = text;
+ }
+
+ public int Key { get; }
+ public string Text { get; }
+
+ public int CompareTo(Item other) =>
+ this.Key.CompareTo(other.Key);
+
+ public override string ToString() =>
+ $"({this.Key}, {this.Text})";
+}
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSort/DensePartialSort3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSort/DensePartialSort3.linq
new file mode 100644
index 000000000..362f7076a
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSort/DensePartialSort3.linq
@@ -0,0 +1,32 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = new[]
+{
+ (key: 5, text: "1"),
+ (key: 5, text: "2"),
+ (key: 4, text: "3"),
+ (key: 4, text: "4"),
+ (key: 3, text: "5"),
+ (key: 3, text: "6"),
+ (key: 2, text: "7"),
+ (key: 2, text: "8"),
+ (key: 1, text: "9"),
+ (key: 1, text: "10"),
+};
+
+// Get the top N sets of items
+var result = sequence
+ .DensePartialSort(
+ 3,
+ Comparer<(int key, string text)>.Create((x, y) => x.key.CompareTo(y.key)));
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [(1, 9), (1, 10), (2, 7), (2, 8), (3, 5), (3, 6)]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSort/DensePartialSort4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSort/DensePartialSort4.linq
new file mode 100644
index 000000000..dbb96390f
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSort/DensePartialSort4.linq
@@ -0,0 +1,33 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = new[]
+{
+ (key: 5, text: "1"),
+ (key: 5, text: "2"),
+ (key: 4, text: "3"),
+ (key: 4, text: "4"),
+ (key: 3, text: "5"),
+ (key: 3, text: "6"),
+ (key: 2, text: "7"),
+ (key: 2, text: "8"),
+ (key: 1, text: "9"),
+ (key: 1, text: "10"),
+};
+
+// Get the top N sets of items
+var result = sequence
+ .DensePartialSort(
+ 3,
+ Comparer<(int key, string text)>.Create((x, y) => x.key.CompareTo(y.key)),
+ OrderByDirection.Descending);
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [(5, 1), (5, 2), (4, 3), (4, 4), (3, 5), (3, 6)]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSortBy/DensePartialSortBy1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSortBy/DensePartialSortBy1.linq
new file mode 100644
index 000000000..238b601c6
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSortBy/DensePartialSortBy1.linq
@@ -0,0 +1,32 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = new[]
+{
+ (key: 5, text: "1"),
+ (key: 5, text: "2"),
+ (key: 4, text: "3"),
+ (key: 4, text: "4"),
+ (key: 3, text: "5"),
+ (key: 3, text: "6"),
+ (key: 2, text: "7"),
+ (key: 2, text: "8"),
+ (key: 1, text: "9"),
+ (key: 1, text: "10"),
+};
+
+// Get the top N sets of items
+var result = sequence
+ .DensePartialSortBy(
+ 3,
+ x => x.key);
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [(1, 9), (1, 10), (2, 7), (2, 8), (3, 5), (3, 6)]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSortBy/DensePartialSortBy2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSortBy/DensePartialSortBy2.linq
new file mode 100644
index 000000000..537c94b79
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSortBy/DensePartialSortBy2.linq
@@ -0,0 +1,33 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = new[]
+{
+ (key: 5, text: "1"),
+ (key: 5, text: "2"),
+ (key: 4, text: "3"),
+ (key: 4, text: "4"),
+ (key: 3, text: "5"),
+ (key: 3, text: "6"),
+ (key: 2, text: "7"),
+ (key: 2, text: "8"),
+ (key: 1, text: "9"),
+ (key: 1, text: "10"),
+};
+
+// Get the top N sets of items
+var result = sequence
+ .DensePartialSortBy(
+ 3,
+ x => x.key,
+ OrderByDirection.Descending);
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [(5, 1), (5, 2), (4, 3), (4, 4), (3, 5), (3, 6)]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSortBy/DensePartialSortBy3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSortBy/DensePartialSortBy3.linq
new file mode 100644
index 000000000..0690b5743
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSortBy/DensePartialSortBy3.linq
@@ -0,0 +1,33 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = new[]
+{
+ (key: 5, text: "1"),
+ (key: 5, text: "2"),
+ (key: 4, text: "3"),
+ (key: 4, text: "4"),
+ (key: 3, text: "5"),
+ (key: 3, text: "6"),
+ (key: 2, text: "7"),
+ (key: 2, text: "8"),
+ (key: 1, text: "9"),
+ (key: 1, text: "10"),
+};
+
+// Get the top N sets of items
+var result = sequence
+ .DensePartialSortBy(
+ 1,
+ x => x.key,
+ Comparer.Create((x, y) => (x % 2).CompareTo(y % 2)));
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [(4, 3), (4, 4), (2, 7), (2, 8)]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSortBy/DensePartialSortBy4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSortBy/DensePartialSortBy4.linq
new file mode 100644
index 000000000..c1c020361
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DensePartialSortBy/DensePartialSortBy4.linq
@@ -0,0 +1,34 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = new[]
+{
+ (key: 5, text: "1"),
+ (key: 5, text: "2"),
+ (key: 4, text: "3"),
+ (key: 4, text: "4"),
+ (key: 3, text: "5"),
+ (key: 3, text: "6"),
+ (key: 2, text: "7"),
+ (key: 2, text: "8"),
+ (key: 1, text: "9"),
+ (key: 1, text: "10"),
+};
+
+// Get the top N sets of items
+var result = sequence
+ .DensePartialSortBy(
+ 1,
+ x => x.key,
+ Comparer.Create((x, y) => (x % 2).CompareTo(y % 2)),
+ OrderByDirection.Descending);
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [(5, 1), (5, 2), (3, 5), (3, 6), (1, 9), (1, 10)]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DenseRank/DenseRank1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DenseRank/DenseRank1.linq
new file mode 100644
index 000000000..f75865f43
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DenseRank/DenseRank1.linq
@@ -0,0 +1,47 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = new Item[]
+{
+ new(key: 5, text: "1"),
+ new(key: 5, text: "2"),
+ new(key: 4, text: "3"),
+ new(key: 4, text: "4"),
+ new(key: 3, text: "5"),
+ new(key: 3, text: "6"),
+ new(key: 2, text: "7"),
+ new(key: 2, text: "8"),
+ new(key: 1, text: "9"),
+ new(key: 1, text: "10"),
+};
+
+// Rank the items in the sequence
+var result = sequence.DenseRank();
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [((1, 9), 1), ((1, 10), 1), ((2, 7), 2), ((2, 8), 2), ((3, 5), 3), ((3, 6), 3), ((4, 3), 4), ((4, 4), 4), ((5, 1), 5), ((5, 2), 5)]
+
+class Item : IComparable
-
+{
+ public Item(int key, string text)
+ {
+ Key = key;
+ Text = text;
+ }
+
+ public int Key { get; }
+ public string Text { get; }
+
+ public int CompareTo(Item other) =>
+ this.Key.CompareTo(other.Key);
+
+ public override string ToString() =>
+ $"({this.Key}, {this.Text})";
+}
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DenseRank/DenseRank3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DenseRank/DenseRank3.linq
new file mode 100644
index 000000000..fdcf1b042
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DenseRank/DenseRank3.linq
@@ -0,0 +1,31 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = new[]
+{
+ (key: 5, text: "1"),
+ (key: 5, text: "2"),
+ (key: 4, text: "3"),
+ (key: 4, text: "4"),
+ (key: 3, text: "5"),
+ (key: 3, text: "6"),
+ (key: 2, text: "7"),
+ (key: 2, text: "8"),
+ (key: 1, text: "9"),
+ (key: 1, text: "10"),
+};
+
+// Get the top N sets of items
+var result = sequence
+ .DenseRank(
+ Comparer<(int key, string text)>.Create((x, y) => x.key.CompareTo(y.key)));
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [((1, 9), 1), ((1, 10), 1), ((2, 7), 2), ((2, 8), 2), ((3, 5), 3), ((3, 6), 3), ((4, 3), 4), ((4, 4), 4), ((5, 1), 5), ((5, 2), 5)]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DenseRankBy/DenseRankBy1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DenseRankBy/DenseRankBy1.linq
new file mode 100644
index 000000000..4124f92f4
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DenseRankBy/DenseRankBy1.linq
@@ -0,0 +1,31 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = new[]
+{
+ (key: 5, text: "1"),
+ (key: 5, text: "2"),
+ (key: 4, text: "3"),
+ (key: 4, text: "4"),
+ (key: 3, text: "5"),
+ (key: 3, text: "6"),
+ (key: 2, text: "7"),
+ (key: 2, text: "8"),
+ (key: 1, text: "9"),
+ (key: 1, text: "10"),
+};
+
+// Get the top N sets of items
+var result = sequence
+ .DenseRankBy(
+ x => x.key);
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [((1, 9), 1), ((1, 10), 1), ((2, 7), 2), ((2, 8), 2), ((3, 5), 3), ((3, 6), 3), ((4, 3), 4), ((4, 4), 4), ((5, 1), 5), ((5, 2), 5)]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DenseRankBy/DenseRankBy3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DenseRankBy/DenseRankBy3.linq
new file mode 100644
index 000000000..b2ceeeffc
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DenseRankBy/DenseRankBy3.linq
@@ -0,0 +1,32 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = new[]
+{
+ (key: 5, text: "1"),
+ (key: 5, text: "2"),
+ (key: 4, text: "3"),
+ (key: 4, text: "4"),
+ (key: 3, text: "5"),
+ (key: 3, text: "6"),
+ (key: 2, text: "7"),
+ (key: 2, text: "8"),
+ (key: 1, text: "9"),
+ (key: 1, text: "10"),
+};
+
+// Get the top N sets of items
+var result = sequence
+ .DenseRankBy(
+ x => x.key,
+ Comparer.Create((x, y) => (x % 2).CompareTo(y % 2)));
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [((4, 3), 1), ((4, 4), 1), ((2, 7), 1), ((2, 8), 1), ((5, 1), 2), ((5, 2), 2), ((3, 5), 2), ((3, 6), 2), ((1, 9), 2), ((1, 10), 2)]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DistinctUntilChanged/DistinctUntilChanged1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DistinctUntilChanged/DistinctUntilChanged1.linq
new file mode 100644
index 000000000..af11f25a6
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DistinctUntilChanged/DistinctUntilChanged1.linq
@@ -0,0 +1,52 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = new Item[]
+{
+ new(key: 3, text: "1"),
+ new(key: 3, text: "2"),
+ new(key: 2, text: "3"),
+ new(key: 2, text: "4"),
+ new(key: 1, text: "5"),
+ new(key: 1, text: "6"),
+ new(key: 3, text: "7"),
+ new(key: 3, text: "8"),
+ new(key: 2, text: "9"),
+ new(key: 2, text: "10"),
+ new(key: 1, text: "11"),
+ new(key: 1, text: "12"),
+};
+
+// Get distinct
+var result = sequence.DistinctUntilChanged();
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [(3, 1), (2, 3), (1, 5), (3, 7), (2, 9), (1, 11)]
+
+class Item : IEquatable
-
+{
+ public Item(int key, string text)
+ {
+ Key = key;
+ Text = text;
+ }
+
+ public int Key { get; }
+ public string Text { get; }
+
+ public bool Equals(Item other) =>
+ this.Key == other.Key;
+
+ public override int GetHashCode() =>
+ this.Key.GetHashCode();
+
+ public override string ToString() =>
+ $"({this.Key}, {this.Text})";
+}
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DistinctUntilChanged/DistinctUntilChanged2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DistinctUntilChanged/DistinctUntilChanged2.linq
new file mode 100644
index 000000000..c65741a45
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DistinctUntilChanged/DistinctUntilChanged2.linq
@@ -0,0 +1,57 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = new Item[]
+{
+ new(key: 3, text: "1"),
+ new(key: 3, text: "2"),
+ new(key: 2, text: "3"),
+ new(key: 2, text: "4"),
+ new(key: 1, text: "5"),
+ new(key: 1, text: "6"),
+ new(key: 3, text: "7"),
+ new(key: 3, text: "8"),
+ new(key: 2, text: "9"),
+ new(key: 2, text: "10"),
+ new(key: 1, text: "11"),
+ new(key: 1, text: "12"),
+};
+
+// Get distinct
+var result = sequence
+ .DistinctUntilChanged(
+ new ItemComparer());
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [(3, 1), (2, 3), (1, 5), (3, 7), (2, 9), (1, 11)]
+
+class Item
+{
+ public Item(int key, string text)
+ {
+ Key = key;
+ Text = text;
+ }
+
+ public int Key { get; }
+ public string Text { get; }
+
+ public override string ToString() =>
+ $"({this.Key}, {this.Text})";
+}
+
+class ItemComparer : IEqualityComparer
-
+{
+ public bool Equals(Item x, Item y) =>
+ x.Key == y.Key;
+
+ public int GetHashCode(Item obj) =>
+ obj.Key.GetHashCode();
+}
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DistinctUntilChanged/DistinctUntilChanged3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DistinctUntilChanged/DistinctUntilChanged3.linq
new file mode 100644
index 000000000..e2b588f0e
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DistinctUntilChanged/DistinctUntilChanged3.linq
@@ -0,0 +1,32 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = new[]
+{
+ (key: 3, text: "1"),
+ (key: 3, text: "2"),
+ (key: 2, text: "3"),
+ (key: 2, text: "4"),
+ (key: 1, text: "5"),
+ (key: 1, text: "6"),
+ (key: 3, text: "7"),
+ (key: 3, text: "8"),
+ (key: 2, text: "9"),
+ (key: 2, text: "10"),
+ (key: 1, text: "11"),
+ (key: 1, text: "12"),
+};
+
+// Get distinct
+var result = sequence
+ .DistinctUntilChanged(x => x.key);
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [(3, 1), (2, 3), (1, 5), (3, 7), (2, 9), (1, 11)]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DistinctUntilChanged/DistinctUntilChanged4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DistinctUntilChanged/DistinctUntilChanged4.linq
new file mode 100644
index 000000000..efcb439ec
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DistinctUntilChanged/DistinctUntilChanged4.linq
@@ -0,0 +1,34 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = new[]
+{
+ (key: "aa", text: "1"),
+ (key: "Aa", text: "2"),
+ (key: "AA", text: "3"),
+ (key: "BB", text: "4"),
+ (key: "bB", text: "5"),
+ (key: "Cc", text: "6"),
+ (key: "CC", text: "7"),
+ (key: "Aa", text: "8"),
+ (key: "aA", text: "9"),
+ (key: "bb", text: "10"),
+ (key: "bB", text: "11"),
+ (key: "CC", text: "12"),
+};
+
+// Get distinct
+var result = sequence
+ .DistinctUntilChanged(
+ x => x.key,
+ StringComparer.OrdinalIgnoreCase);
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [(aa, 1), (BB, 4), (Cc, 6), (Aa, 8), (bb, 10), (CC, 12)]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Do/Do1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Do/Do1.linq
new file mode 100644
index 000000000..3099001ad
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Do/Do1.linq
@@ -0,0 +1,18 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 5);
+
+// Execute an action for each element
+var result = sequence
+ .Do(i => Console.Write($"{i}, "));
+
+Console.WriteLine("Before");
+result.Consume();
+Console.WriteLine("After");
+
+// This code produces the following output:
+// Before
+// 1, 2, 3, 4, 5, After
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Do/Do2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Do/Do2.linq
new file mode 100644
index 000000000..f1fcf5e81
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Do/Do2.linq
@@ -0,0 +1,21 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 5);
+
+// Execute an action for each element, and on completion
+var result = sequence
+ .Do(
+ i => Console.Write($"{i}, "),
+ () => Console.WriteLine("Completed"));
+
+Console.WriteLine("Before");
+result.Consume();
+Console.WriteLine("After");
+
+// This code produces the following output:
+// Before
+// 1, 2, 3, 4, 5, Completed
+// After
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Do/Do3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Do/Do3.linq
new file mode 100644
index 000000000..12466a0c5
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Do/Do3.linq
@@ -0,0 +1,25 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 4).Concat(SuperEnumerable.Throw(new InvalidOperationException()));
+
+// Execute an action for each element, on error, and on completion
+var result = sequence
+ .Do(
+ i => Console.Write($"{i}, "),
+ ex => Console.WriteLine("Failed: " + ex.Message));
+
+Console.WriteLine("Before");
+try
+{
+ result.Consume();
+}
+catch (InvalidOperationException) {}
+Console.WriteLine("After");
+
+// This code produces the following output:
+// Before
+// 1, 2, 3, 4, Failed: Operation is not valid due to the current state of the object.
+// After
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Do/Do4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Do/Do4.linq
new file mode 100644
index 000000000..3fdbe2d16
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Do/Do4.linq
@@ -0,0 +1,38 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var flag = false;
+var sequence = SuperEnumerable.If(
+ () => flag,
+ Enumerable.Range(1, 5),
+ Enumerable.Range(1, 4).Concat(SuperEnumerable.Throw(new InvalidOperationException())));
+
+// Execute an action for each element, on error, and on completion
+var result = sequence
+ .Do(
+ i => Console.Write($"{i}, "),
+ ex => Console.WriteLine("Failed: " + ex.Message),
+ () => Console.WriteLine("Completed"));
+
+Console.WriteLine("Before 1");
+try
+{
+ result.Consume();
+}
+catch (InvalidOperationException) {}
+Console.WriteLine("After 1");
+
+flag = true;
+Console.WriteLine("Before 2");
+result.Consume();
+Console.WriteLine("After 2");
+
+// This code produces the following output:
+// Before 1
+// 1, 2, 3, 4, Failed: Operation is not valid due to the current state of the object.
+// After 1
+// Before 2
+// 1, 2, 3, 4, 5, Completed
+// After 2
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/DoWhile/DoWhile.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DoWhile/DoWhile.linq
new file mode 100644
index 000000000..ca06a0333
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/DoWhile/DoWhile.linq
@@ -0,0 +1,27 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var executionCount = 0;
+var sequence = Enumerable.Range(1, 5)
+ .Do(_ => executionCount++);
+
+// Execute an action for each element
+var loopCount = 0;
+var result = sequence
+ .DoWhile(() => loopCount++ < 2);
+
+Console.WriteLine($"Before (execCount: {executionCount})");
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+Console.WriteLine($"After (execCount: {executionCount})");
+
+// This code produces the following output:
+// Before (execCount: 0)
+// [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
+// After (execCount: 5)
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/EndsWith/EndsWith1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EndsWith/EndsWith1.linq
new file mode 100644
index 000000000..51b139c3c
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EndsWith/EndsWith1.linq
@@ -0,0 +1,15 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 5);
+
+// Determine if sequence ends with the ends sequence
+var ends = Enumerable.Range(4, 2);
+var result = sequence.EndsWith(ends);
+
+Console.WriteLine($"EndsWith: {result}");
+
+// This code produces the following output:
+// EndsWith: True
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/EndsWith/EndsWith2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EndsWith/EndsWith2.linq
new file mode 100644
index 000000000..985743cde
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EndsWith/EndsWith2.linq
@@ -0,0 +1,39 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var pets1 = new List { new("Turbo", 2), new("Peanut", 8), };
+var pets2 = new List { new("Peanut", 8), };
+
+// Determine if pets1 ends with the pets2 sequence.
+var result = pets1
+ .EndsWith(
+ pets2,
+ new PetComparer());
+
+Console.WriteLine($"EndsWith: {result}");
+
+// This code produces the following output:
+// EndsWith: True
+
+class Pet
+{
+ public Pet(string name, int age)
+ {
+ this.Name = name;
+ this.Age = age;
+ }
+
+ public string Name { get; }
+ public int Age { get; }
+}
+
+class PetComparer : IEqualityComparer
+{
+ public bool Equals(Pet x, Pet y) =>
+ x.Name == y.Name
+ && x.Age == y.Age;
+ public int GetHashCode(Pet x) =>
+ HashCode.Combine(x.Name, x.Age);
+}
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip1.linq
new file mode 100644
index 000000000..3726a59e8
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip1.linq
@@ -0,0 +1,18 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var seq1 = new[] { "aaa", "bb", "c", "ddd", };
+var seq2 = new[] { 1, 2, 3, 4, };
+
+// Determine if sequence ends with the ends sequence
+var result = seq1.EquiZip(seq2);
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [(aaa, 1), (bb, 2), (c, 3), (ddd, 4)]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip2.linq
new file mode 100644
index 000000000..b458a5d8f
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip2.linq
@@ -0,0 +1,21 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var seq1 = new[] { "aaa", "bb", "c", "ddd", };
+var seq2 = new[] { 1, 2, 3, 4, };
+
+// Determine if sequence ends with the ends sequence
+var result = seq1
+ .EquiZip(
+ seq2,
+ (a, b) => new { Key = a, Value = b, });
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [{ Key = aaa, Value = 1 }, { Key = bb, Value = 2 }, { Key = c, Value = 3 }, { Key = ddd, Value = 4 }]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip3.linq
new file mode 100644
index 000000000..f9ead98dc
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip3.linq
@@ -0,0 +1,22 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var seq1 = new[] { "aaa", "bb", "c", "ddd", };
+var seq2 = new[] { 1, 2, 3, 4, };
+var seq3 = new[] { 20, 5, 7, 12 };
+
+// Determine if sequence ends with the ends sequence
+var result = seq1
+ .EquiZip(
+ seq2,
+ seq3);
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [(aaa, 1, 20), (bb, 2, 5), (c, 3, 7), (ddd, 4, 12)]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip4.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip4.linq
new file mode 100644
index 000000000..40fc9b05f
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip4.linq
@@ -0,0 +1,23 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var seq1 = new[] { "aaa", "bb", "c", "ddd", };
+var seq2 = new[] { 1, 2, 3, 4, };
+var seq3 = new[] { 20, 5, 7, 12 };
+
+// Determine if sequence ends with the ends sequence
+var result = seq1
+ .EquiZip(
+ seq2,
+ seq3,
+ (a, b, c) => new { A = a, B = b, C = c, });
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [{ A = aaa, B = 1, C = 20 }, { A = bb, B = 2, C = 5 }, { A = c, B = 3, C = 7 }, { A = ddd, B = 4, C = 12 }]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip5.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip5.linq
new file mode 100644
index 000000000..24bd54190
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip5.linq
@@ -0,0 +1,24 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var seq1 = new[] { "aaa", "bb", "c", "ddd", };
+var seq2 = new[] { 1, 2, 3, 4, };
+var seq3 = new[] { 20, 5, 7, 12 };
+var seq4 = new[] { "zz", "yyyy", "xxx", "w", };
+
+// Determine if sequence ends with the ends sequence
+var result = seq1
+ .EquiZip(
+ seq2,
+ seq3,
+ seq4);
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [(aaa, 1, 20, zz), (bb, 2, 5, yyyy), (c, 3, 7, xxx), (ddd, 4, 12, w)]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip6.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip6.linq
new file mode 100644
index 000000000..ce407d1dc
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/EquiZip/EquiZip6.linq
@@ -0,0 +1,31 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var seq1 = new[] { "aaa", "bb", "c", "ddd", };
+var seq2 = new[] { 1, 2, 3, 4, };
+var seq3 = new[] { 20, 5, 7, 12 };
+var seq4 = new[] { "zz", "yyyy", "xxx", "w", };
+
+// Determine if sequence ends with the ends sequence
+var result = seq1
+ .EquiZip(
+ seq2,
+ seq3,
+ seq4,
+ (a, b, c, d) => new
+ {
+ A = a,
+ B = b,
+ C = c,
+ D = d,
+ });
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [{ A = aaa, B = 1, C = 20, D = zz }, { A = bb, B = 2, C = 5, D = yyyy }, { A = c, B = 3, C = 7, D = xxx }, { A = ddd, B = 4, C = 12, D = w }]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Evaluate/Evaluate.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Evaluate/Evaluate.linq
new file mode 100644
index 000000000..45743ecbc
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Evaluate/Evaluate.linq
@@ -0,0 +1,20 @@
+
+ SuperLinq
+ SuperLinq
+
+
+int Func1() => 3;
+int Func2() => 5;
+int Func3() => 1;
+
+// Execute an action for each element
+var result = SuperEnumerable
+ .Evaluate(new[] { Func1, Func2, Func3 });
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [3, 5, 1]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Exactly/Exactly.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Exactly/Exactly.linq
new file mode 100644
index 000000000..93a4cebbb
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Exactly/Exactly.linq
@@ -0,0 +1,21 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 5);
+
+foreach (var x in Enumerable.Range(3, 5))
+{
+ // Check that a sequence has an exact size
+ var result = sequence.Exactly(x);
+
+ Console.WriteLine($"Exactly {x}: {result}");
+}
+
+// This code produces the following output:
+// Exactly 3: False
+// Exactly 4: False
+// Exactly 5: True
+// Exactly 6: False
+// Exactly 7: False
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ExceptBy/ExceptBy1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ExceptBy/ExceptBy1.linq
new file mode 100644
index 000000000..89f81f4fe
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ExceptBy/ExceptBy1.linq
@@ -0,0 +1,17 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = new[] { "aaa", "bb", "c", "dddd", };
+
+// Determine if sequence ends with the ends sequence
+var result = sequence.ExceptBy(new[] { "a", "b", }, s => s[0]);
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [c, dddd]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/ExceptBy/ExceptBy2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ExceptBy/ExceptBy2.linq
new file mode 100644
index 000000000..d49f7719d
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/ExceptBy/ExceptBy2.linq
@@ -0,0 +1,27 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = new[]
+{
+ (key: "aaa", value: 1),
+ (key: "bb", value: 2),
+ (key: "c", value: 3),
+ (key: "dddd", value: 4),
+};
+
+// Determine if sequence ends with the ends sequence
+var result = sequence
+ .ExceptBy(
+ new[] { (key: "A", value: 13), (key: "D", value: 14), },
+ s => s.key[..1],
+ StringComparer.OrdinalIgnoreCase);
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [(bb, 2), (c, 3)]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Exclude/Exclude.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Exclude/Exclude.linq
new file mode 100644
index 000000000..56829d8da
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Exclude/Exclude.linq
@@ -0,0 +1,18 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 10);
+
+// Execute an action for each element
+var result = sequence
+ .Exclude(3, 5);
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [1, 2, 3, 9, 10]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FallbackIfEmpty/FallbackIfEmpty1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FallbackIfEmpty/FallbackIfEmpty1.linq
new file mode 100644
index 000000000..34a409d9d
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FallbackIfEmpty/FallbackIfEmpty1.linq
@@ -0,0 +1,30 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var flag = false;
+var sequence = SuperEnumerable.Defer(
+ () =>
+ {
+ if (flag) return Enumerable.Empty();
+ flag = true;
+ return Enumerable.Range(1, 5);
+ });
+
+// Replace a sequence if it is empty.
+var result = sequence.FallbackIfEmpty(10, 11, 12);
+
+Console.WriteLine(
+ "Non-Empty: [" +
+ string.Join(", ", result) +
+ "]");
+
+Console.WriteLine(
+ "Empty: [" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// Non-Empty: [1, 2, 3, 4, 5]
+// Empty: [10, 11, 12]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FallbackIfEmpty/FallbackIfEmpty2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FallbackIfEmpty/FallbackIfEmpty2.linq
new file mode 100644
index 000000000..39bc99ef8
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FallbackIfEmpty/FallbackIfEmpty2.linq
@@ -0,0 +1,32 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var flag = false;
+var sequence = SuperEnumerable.Defer(
+ () =>
+ {
+ if (flag) return Enumerable.Empty();
+ flag = true;
+ return Enumerable.Range(1, 5);
+ });
+
+// Replace a sequence if it is empty.
+var result = sequence
+ .FallbackIfEmpty(
+ Enumerable.Range(20, 3));
+
+Console.WriteLine(
+ "Non-Empty: [" +
+ string.Join(", ", result) +
+ "]");
+
+Console.WriteLine(
+ "Empty: [" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// Non-Empty: [1, 2, 3, 4, 5]
+// Empty: [20, 21, 22]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillBackward/FillBackward1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillBackward/FillBackward1.linq
new file mode 100644
index 000000000..8cbb5eca3
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillBackward/FillBackward1.linq
@@ -0,0 +1,17 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = new int?[] { null, null, 1, 2, null, null, null, 3, 4, null, null, };
+
+// Fill in missing elements from later elements
+var result = sequence.FillBackward();
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [1, 1, 1, 2, 3, 3, 3, 3, 4, , ]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillBackward/FillBackward2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillBackward/FillBackward2.linq
new file mode 100644
index 000000000..6e11f824b
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillBackward/FillBackward2.linq
@@ -0,0 +1,19 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 10);
+
+// Fill in missing elements from later elements
+var result = sequence
+ .FillBackward(
+ i => i % 3 < 2);
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [2, 2, 5, 5, 5, 8, 8, 8, 9, 10]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillBackward/FillBackward3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillBackward/FillBackward3.linq
new file mode 100644
index 000000000..fd50eb989
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillBackward/FillBackward3.linq
@@ -0,0 +1,20 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 10);
+
+// Fill in missing elements from later elements
+var result = sequence
+ .FillBackward(
+ i => i % 3 < 2,
+ (cur, nxt) => cur * nxt * 100);
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [200, 2, 1500, 2000, 5, 4800, 5600, 8, 9, 10]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillForward/FillForward1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillForward/FillForward1.linq
new file mode 100644
index 000000000..f43e26996
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillForward/FillForward1.linq
@@ -0,0 +1,17 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = new int?[] { null, null, 1, 2, null, null, null, 3, 4, null, null, };
+
+// Fill in missing elements from previous elements
+var result = sequence.FillForward();
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [, , 1, 2, 2, 2, 2, 3, 4, 4, 4]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillForward/FillForward2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillForward/FillForward2.linq
new file mode 100644
index 000000000..305eeb28f
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillForward/FillForward2.linq
@@ -0,0 +1,19 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 10);
+
+// Fill in missing elements from previous elements
+var result = sequence
+ .FillForward(
+ i => i % 3 < 2);
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [1, 2, 2, 2, 5, 5, 5, 8, 8, 8]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillForward/FillForward3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillForward/FillForward3.linq
new file mode 100644
index 000000000..d71e6fbfb
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FillForward/FillForward3.linq
@@ -0,0 +1,20 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 10);
+
+// Fill in missing elements from previous elements
+var result = sequence
+ .FillForward(
+ i => i % 3 < 2,
+ (cur, nxt) => cur * nxt * 100);
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [1, 2, 600, 800, 5, 3000, 3500, 8, 7200, 8000]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Finally/Finally.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Finally/Finally.linq
new file mode 100644
index 000000000..a1eead01b
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Finally/Finally.linq
@@ -0,0 +1,16 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = Enumerable.Range(1, 5);
+
+// Execute an action when enumeration is complete, regardless of success or fail.
+var result = sequence
+ .Do(i => Console.Write($"{i}, "))
+ .Finally(() => Console.WriteLine("Completed"));
+
+result.Consume();
+
+// This code produces the following output:
+// 1, 2, 3, 4, 5, Completed
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindIndex/FindIndex1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindIndex/FindIndex1.linq
new file mode 100644
index 000000000..05d0d9eaa
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindIndex/FindIndex1.linq
@@ -0,0 +1,33 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = new[]
+{
+ (key: 2, name: "Frank"),
+ (key: 3, name: "Jill"),
+ (key: 5, name: "Dave"),
+ (key: 8, name: "Jack"),
+ (key: 12, name: "Judith"),
+ (key: 14, name: "Robert"),
+ (key: 1, name: "Adam"),
+};
+
+// Find the first index that matches a condition
+Console.WriteLine(
+ "'J' starts at index {0}",
+ sequence.FindIndex(x => x.name.StartsWith("J")));
+
+Console.WriteLine(
+ "'Ju' starts at index {0}",
+ sequence.FindIndex(x => x.name.StartsWith("Ju")));
+
+Console.WriteLine(
+ "'K' starts at index {0}",
+ sequence.FindIndex(x => x.name.StartsWith("K")));
+
+// This code produces the following output:
+// 'J' starts at index 1
+// 'Ju' starts at index 4
+// 'K' starts at index -1
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindIndex/FindIndex2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindIndex/FindIndex2.linq
new file mode 100644
index 000000000..ec0402c9d
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindIndex/FindIndex2.linq
@@ -0,0 +1,32 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = new[]
+{
+ (key: 2, name: "Frank"),
+ (key: 3, name: "Jill"),
+ (key: 5, name: "Dave"),
+ (key: 8, name: "Jack"),
+ (key: 12, name: "Judith"),
+ (key: 14, name: "Robert"),
+ (key: 1, name: "Adam"),
+};
+
+// Find the first index that matches a condition
+Console.WriteLine(
+ "'J' starts at index {0}, after index 4",
+ sequence.FindIndex(
+ x => x.name.StartsWith("J"),
+ 4));
+
+Console.WriteLine(
+ "'J' starts at index {0}, after index ^2",
+ sequence.FindIndex(
+ x => x.name.StartsWith("J"),
+ ^2));
+
+// This code produces the following output:
+// 'J' starts at index 4, after index 4
+// 'J' starts at index -1, after index ^2
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindIndex/FindIndex3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindIndex/FindIndex3.linq
new file mode 100644
index 000000000..ecc19e593
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindIndex/FindIndex3.linq
@@ -0,0 +1,34 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = new[]
+{
+ (key: 2, name: "Frank"),
+ (key: 3, name: "Jill"),
+ (key: 5, name: "Dave"),
+ (key: 8, name: "Jack"),
+ (key: 12, name: "Judith"),
+ (key: 14, name: "Robert"),
+ (key: 1, name: "Adam"),
+};
+
+// Find the first index that matches a condition
+Console.WriteLine(
+ "'J' starts at index {0}, after index 2-4",
+ sequence.FindIndex(
+ x => x.name.StartsWith("J"),
+ 2,
+ 3));
+
+Console.WriteLine(
+ "'J' starts at index {0}, after index 2-2",
+ sequence.FindIndex(
+ x => x.name.StartsWith("J"),
+ 2,
+ 1));
+
+// This code produces the following output:
+// 'J' starts at index 3, after index 2-4
+// 'J' starts at index -1, after index 2-2
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindLastIndex/FindLastIndex1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindLastIndex/FindLastIndex1.linq
new file mode 100644
index 000000000..ea6dbda61
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindLastIndex/FindLastIndex1.linq
@@ -0,0 +1,36 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = new[]
+{
+ (key: 2, name: "Frank"),
+ (key: 3, name: "Jill"),
+ (key: 5, name: "Dave"),
+ (key: 8, name: "Jack"),
+ (key: 12, name: "Judith"),
+ (key: 14, name: "Robert"),
+ (key: 1, name: "Adam"),
+};
+
+// Find the first index that matches a condition
+Console.WriteLine(
+ "'J' starts at index {0}",
+ sequence.FindLastIndex(
+ x => x.name.StartsWith("J")));
+
+Console.WriteLine(
+ "'Ji' starts at index {0}",
+ sequence.FindLastIndex(
+ x => x.name.StartsWith("Ji")));
+
+Console.WriteLine(
+ "'K' starts at index {0}",
+ sequence.FindLastIndex(
+ x => x.name.StartsWith("K")));
+
+// This code produces the following output:
+// 'J' starts at index 4
+// 'Ji' starts at index 1
+// 'K' starts at index -1
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindLastIndex/FindLastIndex2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindLastIndex/FindLastIndex2.linq
new file mode 100644
index 000000000..0a705c41c
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindLastIndex/FindLastIndex2.linq
@@ -0,0 +1,32 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = new[]
+{
+ (key: 2, name: "Frank"),
+ (key: 3, name: "Jill"),
+ (key: 5, name: "Dave"),
+ (key: 8, name: "Jack"),
+ (key: 12, name: "Judith"),
+ (key: 14, name: "Robert"),
+ (key: 1, name: "Adam"),
+};
+
+// Find the first index that matches a condition
+Console.WriteLine(
+ "'J' starts at index {0}, before index 0",
+ sequence.FindLastIndex(
+ x => x.name.StartsWith("J"),
+ 0));
+
+Console.WriteLine(
+ "'J' starts at index {0}, before index ^2",
+ sequence.FindLastIndex(
+ x => x.name.StartsWith("J"),
+ ^2));
+
+// This code produces the following output:
+// 'J' starts at index -1, before index 0
+// 'J' starts at index 4, before index ^2
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindLastIndex/FindLastIndex3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindLastIndex/FindLastIndex3.linq
new file mode 100644
index 000000000..8c1e23e38
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/FindLastIndex/FindLastIndex3.linq
@@ -0,0 +1,33 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = new[]
+{
+ (key: 2, name: "Frank"),
+ (key: 3, name: "Jill"),
+ (key: 5, name: "Dave"),
+ (key: 8, name: "Jack"),
+ (key: 12, name: "Judith"),
+ (key: 14, name: "Robert"),
+ (key: 1, name: "Adam"),
+};
+
+// Find the first index that matches a condition
+Console.WriteLine(
+ "'J' starts at index {0}, before index 0",
+ sequence.FindLastIndex(
+ x => x.name.StartsWith("J"),
+ 1,
+ 1));
+
+Console.WriteLine(
+ "'J' starts at index {0}, before index ^2",
+ sequence.FindLastIndex(
+ x => x.name.StartsWith("J"),
+ ^2));
+
+// This code produces the following output:
+// 'J' starts at index -1, before index 0
+// 'J' starts at index 4, before index ^2
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Flatten/Flatten1.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Flatten/Flatten1.linq
new file mode 100644
index 000000000..8dc301420
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Flatten/Flatten1.linq
@@ -0,0 +1,34 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = new object[]
+{
+ 1, 2, 3,
+ new object[]
+ {
+ 4, 5,
+ new object[] { 6, 7, },
+ 8, 9, 10,
+ },
+ 11,
+ new object[]
+ {
+ 12, 13, 14,
+ new object[] { 15, 16, 17, },
+ 18, 19,
+ },
+ 20,
+};
+
+// Flatten a hierarchical sequence
+var result = sequence.Flatten();
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Flatten/Flatten2.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Flatten/Flatten2.linq
new file mode 100644
index 000000000..690860d3c
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Flatten/Flatten2.linq
@@ -0,0 +1,34 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = new object[]
+{
+ 1, 2, 3,
+ new object[]
+ {
+ 4, 5,
+ new int[] { 6, 7, 8, },
+ },
+ 9, 10, 11,
+ new object[]
+ {
+ 12, 13, 14,
+ new object[] { 15, 16, 17, },
+ 18, 19,
+ },
+ 20,
+};
+
+// Flatten a hierarchical sequence
+var result = sequence
+ .Flatten(e => e is not int[]);
+
+Console.WriteLine(
+ "[" +
+ string.Join(", ", result) +
+ "]");
+
+// This code produces the following output:
+// [1, 2, 3, 4, 5, System.Int32[], 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
diff --git a/Docs/SuperLinq.Docs/apidoc/SuperLinq/Flatten/Flatten3.linq b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Flatten/Flatten3.linq
new file mode 100644
index 000000000..ab823bd89
--- /dev/null
+++ b/Docs/SuperLinq.Docs/apidoc/SuperLinq/Flatten/Flatten3.linq
@@ -0,0 +1,40 @@
+
+ SuperLinq
+ SuperLinq
+
+
+var sequence = new object[]
+{
+ true,
+ false,
+ 1,
+ "bar",
+ new object[]
+ {
+ 2,
+ new[]
+ {
+ 3,
+ },
+ },
+ 'c',
+ 4,
+};
+
+// Flatten a hierarchical sequence
+var result = sequence
+ .Flatten(obj =>
+ obj switch
+ {
+ int => null,
+ IEnumerable inner => inner,
+ _ => Enumerable.Empty