diff --git a/src/libraries/System.Formats.Tar/ref/System.Formats.Tar.cs b/src/libraries/System.Formats.Tar/ref/System.Formats.Tar.cs
index 66210cdcaeca4a..e2f283ba384104 100644
--- a/src/libraries/System.Formats.Tar/ref/System.Formats.Tar.cs
+++ b/src/libraries/System.Formats.Tar/ref/System.Formats.Tar.cs
@@ -84,9 +84,13 @@ public enum TarEntryType : byte
public static partial class TarFile
{
public static void CreateFromDirectory(string sourceDirectoryName, System.IO.Stream destination, bool includeBaseDirectory) { }
+ public static void CreateFromDirectory(string sourceDirectoryName, System.IO.Stream destination, bool includeBaseDirectory, System.Formats.Tar.TarEntryFormat format) { }
public static void CreateFromDirectory(string sourceDirectoryName, string destinationFileName, bool includeBaseDirectory) { }
+ public static void CreateFromDirectory(string sourceDirectoryName, string destinationFileName, bool includeBaseDirectory, System.Formats.Tar.TarEntryFormat format) { }
public static System.Threading.Tasks.Task CreateFromDirectoryAsync(string sourceDirectoryName, System.IO.Stream destination, bool includeBaseDirectory, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+ public static System.Threading.Tasks.Task CreateFromDirectoryAsync(string sourceDirectoryName, System.IO.Stream destination, bool includeBaseDirectory, System.Formats.Tar.TarEntryFormat format, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public static System.Threading.Tasks.Task CreateFromDirectoryAsync(string sourceDirectoryName, string destinationFileName, bool includeBaseDirectory, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
+ public static System.Threading.Tasks.Task CreateFromDirectoryAsync(string sourceDirectoryName, string destinationFileName, bool includeBaseDirectory, System.Formats.Tar.TarEntryFormat format, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public static void ExtractToDirectory(System.IO.Stream source, string destinationDirectoryName, bool overwriteFiles) { }
public static void ExtractToDirectory(string sourceFileName, string destinationDirectoryName, bool overwriteFiles) { }
public static System.Threading.Tasks.Task ExtractToDirectoryAsync(System.IO.Stream source, string destinationDirectoryName, bool overwriteFiles, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
diff --git a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarFile.cs b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarFile.cs
index f1d6a059c57350..1853df91b563ec 100644
--- a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarFile.cs
+++ b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarFile.cs
@@ -16,22 +16,29 @@ namespace System.Formats.Tar
///
public static class TarFile
{
+ ///
+ public static void CreateFromDirectory(string sourceDirectoryName, Stream destination, bool includeBaseDirectory)
+ => CreateFromDirectory(sourceDirectoryName, destination, includeBaseDirectory, TarEntryFormat.Pax);
+
///
/// Creates a tar stream that contains all the filesystem entries from the specified directory.
///
/// The path of the directory to archive.
/// The destination stream the archive.
/// to include the base directory name as the first segment in all the names of the archive entries. to exclude the base directory name from the archive entry names.
+ /// One of the enumeration values that specifies the tar entry format to use for the archive.
/// or is .
/// is empty.
/// -or-
/// does not support writing.
/// The directory path was not found.
+ /// is either , or not one of the other enum values.
/// An I/O exception occurred.
- public static void CreateFromDirectory(string sourceDirectoryName, Stream destination, bool includeBaseDirectory)
+ public static void CreateFromDirectory(string sourceDirectoryName, Stream destination, bool includeBaseDirectory, TarEntryFormat format)
{
ArgumentException.ThrowIfNullOrEmpty(sourceDirectoryName);
ArgumentNullException.ThrowIfNull(destination);
+ ValidateFormat(format);
if (!destination.CanWrite)
{
@@ -46,15 +53,20 @@ public static void CreateFromDirectory(string sourceDirectoryName, Stream destin
// Rely on Path.GetFullPath for validation of paths
sourceDirectoryName = Path.GetFullPath(sourceDirectoryName);
- CreateFromDirectoryInternal(sourceDirectoryName, destination, includeBaseDirectory, leaveOpen: true);
+ CreateFromDirectoryInternal(sourceDirectoryName, destination, includeBaseDirectory, leaveOpen: true, format);
}
+ ///
+ public static Task CreateFromDirectoryAsync(string sourceDirectoryName, Stream destination, bool includeBaseDirectory, CancellationToken cancellationToken = default)
+ => CreateFromDirectoryAsync(sourceDirectoryName, destination, includeBaseDirectory, TarEntryFormat.Pax, cancellationToken);
+
///
/// Asynchronously creates a tar stream that contains all the filesystem entries from the specified directory.
///
/// The path of the directory to archive.
/// The destination stream of the archive.
/// to include the base directory name as the first path segment in all the names of the archive entries. to exclude the base directory name from the entry name paths.
+ /// One of the enumeration values that specifies the tar entry format to use for the archive.
/// The token to monitor for cancellation requests. The default value is .
/// A task that represents the asynchronous creation operation.
/// or is .
@@ -62,8 +74,9 @@ public static void CreateFromDirectory(string sourceDirectoryName, Stream destin
/// -or-
/// does not support writing.
/// The directory path was not found.
+ /// is either , or not one of the other enum values.
/// An I/O exception occurred.
- public static Task CreateFromDirectoryAsync(string sourceDirectoryName, Stream destination, bool includeBaseDirectory, CancellationToken cancellationToken = default)
+ public static Task CreateFromDirectoryAsync(string sourceDirectoryName, Stream destination, bool includeBaseDirectory, TarEntryFormat format, CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -71,6 +84,7 @@ public static Task CreateFromDirectoryAsync(string sourceDirectoryName, Stream d
}
ArgumentException.ThrowIfNullOrEmpty(sourceDirectoryName);
ArgumentNullException.ThrowIfNull(destination);
+ ValidateFormat(format);
if (!destination.CanWrite)
{
@@ -85,23 +99,30 @@ public static Task CreateFromDirectoryAsync(string sourceDirectoryName, Stream d
// Rely on Path.GetFullPath for validation of paths
sourceDirectoryName = Path.GetFullPath(sourceDirectoryName);
- return CreateFromDirectoryInternalAsync(sourceDirectoryName, destination, includeBaseDirectory, leaveOpen: true, cancellationToken);
+ return CreateFromDirectoryInternalAsync(sourceDirectoryName, destination, includeBaseDirectory, leaveOpen: true, format, cancellationToken);
}
+ ///
+ public static void CreateFromDirectory(string sourceDirectoryName, string destinationFileName, bool includeBaseDirectory)
+ => CreateFromDirectory(sourceDirectoryName, destinationFileName, includeBaseDirectory, TarEntryFormat.Pax);
+
///
/// Creates a tar file that contains all the filesystem entries from the specified directory.
///
/// The path of the directory to archive.
/// The path of the destination archive file.
/// to include the base directory name as the first path segment in all the names of the archive entries. to exclude the base directory name from the entry name paths.
+ /// One of the enumeration values that specifies the tar entry format to use for the archive.
/// or is .
/// or is empty.
/// The directory path was not found.
+ /// is either , or not one of the other enum values.
/// An I/O exception occurred.
- public static void CreateFromDirectory(string sourceDirectoryName, string destinationFileName, bool includeBaseDirectory)
+ public static void CreateFromDirectory(string sourceDirectoryName, string destinationFileName, bool includeBaseDirectory, TarEntryFormat format)
{
ArgumentException.ThrowIfNullOrEmpty(sourceDirectoryName);
ArgumentException.ThrowIfNullOrEmpty(destinationFileName);
+ ValidateFormat(format);
// Rely on Path.GetFullPath for validation of paths
sourceDirectoryName = Path.GetFullPath(sourceDirectoryName);
@@ -115,22 +136,28 @@ public static void CreateFromDirectory(string sourceDirectoryName, string destin
// Throws if the destination file exists
using FileStream fs = new(destinationFileName, FileMode.CreateNew, FileAccess.Write);
- CreateFromDirectoryInternal(sourceDirectoryName, fs, includeBaseDirectory, leaveOpen: false);
+ CreateFromDirectoryInternal(sourceDirectoryName, fs, includeBaseDirectory, leaveOpen: false, format);
}
+ ///
+ public static Task CreateFromDirectoryAsync(string sourceDirectoryName, string destinationFileName, bool includeBaseDirectory, CancellationToken cancellationToken = default)
+ => CreateFromDirectoryAsync(sourceDirectoryName, destinationFileName, includeBaseDirectory, TarEntryFormat.Pax, cancellationToken);
+
///
/// Asynchronously creates a tar archive from the contents of the specified directory, and outputs them into the specified path. Can optionally include the base directory as the prefix for the entry names.
///
/// The path of the directory to archive.
/// The path of the destination archive file.
/// to include the base directory name as the first path segment in all the names of the archive entries. to exclude the base directory name from the entry name paths.
+ /// One of the enumeration values that specifies the tar entry format to use for the archive.
/// The token to monitor for cancellation requests. The default value is .
/// A task that represents the asynchronous creation operation.
/// or is .
/// or is empty.
/// The directory path was not found.
+ /// is either , or not one of the other enum values.
/// An I/O exception occurred.
- public static Task CreateFromDirectoryAsync(string sourceDirectoryName, string destinationFileName, bool includeBaseDirectory, CancellationToken cancellationToken = default)
+ public static Task CreateFromDirectoryAsync(string sourceDirectoryName, string destinationFileName, bool includeBaseDirectory, TarEntryFormat format, CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -138,6 +165,7 @@ public static Task CreateFromDirectoryAsync(string sourceDirectoryName, string d
}
ArgumentException.ThrowIfNullOrEmpty(sourceDirectoryName);
ArgumentException.ThrowIfNullOrEmpty(destinationFileName);
+ ValidateFormat(format);
// Rely on Path.GetFullPath for validation of paths
sourceDirectoryName = Path.GetFullPath(sourceDirectoryName);
@@ -148,7 +176,7 @@ public static Task CreateFromDirectoryAsync(string sourceDirectoryName, string d
return Task.FromException(new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, sourceDirectoryName)));
}
- return CreateFromDirectoryInternalAsync(sourceDirectoryName, destinationFileName, includeBaseDirectory, cancellationToken);
+ return CreateFromDirectoryInternalAsync(sourceDirectoryName, destinationFileName, includeBaseDirectory, format, cancellationToken);
}
///
@@ -323,11 +351,11 @@ public static Task ExtractToDirectoryAsync(string sourceFileName, string destina
// Creates an archive from the contents of a directory.
// It assumes the sourceDirectoryName is a fully qualified path, and allows choosing if the archive stream should be left open or not.
- private static void CreateFromDirectoryInternal(string sourceDirectoryName, Stream destination, bool includeBaseDirectory, bool leaveOpen)
+ private static void CreateFromDirectoryInternal(string sourceDirectoryName, Stream destination, bool includeBaseDirectory, bool leaveOpen, TarEntryFormat format)
{
VerifyCreateFromDirectoryArguments(sourceDirectoryName, destination);
- using (TarWriter writer = new TarWriter(destination, TarEntryFormat.Pax, leaveOpen))
+ using (TarWriter writer = new TarWriter(destination, format, leaveOpen))
{
DirectoryInfo di = new(sourceDirectoryName);
@@ -353,7 +381,7 @@ private static void CreateFromDirectoryInternal(string sourceDirectoryName, Stre
}
// Asynchronously creates a tar archive from the contents of the specified directory, and outputs them into the specified path.
- private static async Task CreateFromDirectoryInternalAsync(string sourceDirectoryName, string destinationFileName, bool includeBaseDirectory, CancellationToken cancellationToken)
+ private static async Task CreateFromDirectoryInternalAsync(string sourceDirectoryName, string destinationFileName, bool includeBaseDirectory, TarEntryFormat format, CancellationToken cancellationToken)
{
Debug.Assert(!string.IsNullOrEmpty(sourceDirectoryName));
Debug.Assert(!string.IsNullOrEmpty(destinationFileName));
@@ -370,18 +398,18 @@ private static async Task CreateFromDirectoryInternalAsync(string sourceDirector
FileStream archive = new(destinationFileName, options);
await using (archive.ConfigureAwait(false))
{
- await CreateFromDirectoryInternalAsync(sourceDirectoryName, archive, includeBaseDirectory, leaveOpen: false, cancellationToken).ConfigureAwait(false);
+ await CreateFromDirectoryInternalAsync(sourceDirectoryName, archive, includeBaseDirectory, leaveOpen: false, format, cancellationToken).ConfigureAwait(false);
}
}
// Asynchronously creates an archive from the contents of a directory.
// It assumes the sourceDirectoryName is a fully qualified path, and allows choosing if the archive stream should be left open or not.
- private static async Task CreateFromDirectoryInternalAsync(string sourceDirectoryName, Stream destination, bool includeBaseDirectory, bool leaveOpen, CancellationToken cancellationToken)
+ private static async Task CreateFromDirectoryInternalAsync(string sourceDirectoryName, Stream destination, bool includeBaseDirectory, bool leaveOpen, TarEntryFormat format, CancellationToken cancellationToken)
{
VerifyCreateFromDirectoryArguments(sourceDirectoryName, destination);
cancellationToken.ThrowIfCancellationRequested();
- TarWriter writer = new TarWriter(destination, TarEntryFormat.Pax, leaveOpen);
+ TarWriter writer = new TarWriter(destination, format, leaveOpen);
await using (writer.ConfigureAwait(false))
{
DirectoryInfo di = new(sourceDirectoryName);
@@ -534,5 +562,13 @@ private static void VerifyExtractToDirectoryArguments(Stream source, string dest
Debug.Assert(Path.IsPathFullyQualified(destinationDirectoryPath));
Debug.Assert(source.CanRead);
}
+
+ private static void ValidateFormat(TarEntryFormat format)
+ {
+ if (format is < TarEntryFormat.V7 or > TarEntryFormat.Gnu)
+ {
+ throw new ArgumentOutOfRangeException(nameof(format));
+ }
+ }
}
}
diff --git a/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.CreateFromDirectory.File.Tests.cs b/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.CreateFromDirectory.File.Tests.cs
index 81fb9371011716..fd0eb8efb476ec 100644
--- a/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.CreateFromDirectory.File.Tests.cs
+++ b/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.CreateFromDirectory.File.Tests.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
@@ -253,5 +253,41 @@ public void SkipRecursionIntoBaseDirectorySymlink()
Assert.Null(reader.GetNextEntry());
}
+
+ [Theory]
+ [MemberData(nameof(GetTarEntryFormats))]
+ public void CreateFromDirectory_WithFormat(TarEntryFormat format)
+ {
+ using TempDirectory source = new TempDirectory();
+ using TempDirectory destination = new TempDirectory();
+
+ string fileName = "file.txt";
+ File.Create(Path.Join(source.Path, fileName)).Dispose();
+
+ string destinationArchiveFileName = Path.Join(destination.Path, "output.tar");
+ TarFile.CreateFromDirectory(source.Path, destinationArchiveFileName, includeBaseDirectory: false, format);
+
+ using FileStream fileStream = File.OpenRead(destinationArchiveFileName);
+ using TarReader reader = new TarReader(fileStream);
+
+ TarEntry entry = reader.GetNextEntry();
+ Assert.NotNull(entry);
+ Assert.Equal(format, entry.Format);
+ Assert.Equal(fileName, entry.Name);
+
+ Assert.Null(reader.GetNextEntry());
+ }
+
+ [Theory]
+ [MemberData(nameof(GetInvalidTarEntryFormats))]
+ public void CreateFromDirectory_InvalidFormat_Throws(TarEntryFormat format)
+ {
+ using TempDirectory source = new TempDirectory();
+ using TempDirectory destination = new TempDirectory();
+ string destinationArchiveFileName = Path.Join(destination.Path, "output.tar");
+
+ Assert.Throws("format", () =>
+ TarFile.CreateFromDirectory(source.Path, destinationArchiveFileName, includeBaseDirectory: false, format));
+ }
}
}
diff --git a/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.CreateFromDirectory.Stream.Tests.cs b/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.CreateFromDirectory.Stream.Tests.cs
index a525e1ce7ea82e..4eb06da3c8eb61 100644
--- a/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.CreateFromDirectory.Stream.Tests.cs
+++ b/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.CreateFromDirectory.Stream.Tests.cs
@@ -40,5 +40,38 @@ public void NonExistentDirectory_Throws()
using MemoryStream archive = new MemoryStream();
Assert.Throws(() => TarFile.CreateFromDirectory(sourceDirectoryName: dirPath, destination: archive, includeBaseDirectory: false));
}
+
+ [Theory]
+ [MemberData(nameof(GetTarEntryFormats))]
+ public void CreateFromDirectory_WithFormat(TarEntryFormat format)
+ {
+ using TempDirectory source = new TempDirectory();
+ string fileName = "file.txt";
+ File.Create(Path.Join(source.Path, fileName)).Dispose();
+
+ using MemoryStream archive = new MemoryStream();
+ TarFile.CreateFromDirectory(source.Path, archive, includeBaseDirectory: false, format);
+
+ archive.Position = 0;
+ using TarReader reader = new TarReader(archive);
+
+ TarEntry entry = reader.GetNextEntry();
+ Assert.NotNull(entry);
+ Assert.Equal(format, entry.Format);
+ Assert.Equal(fileName, entry.Name);
+
+ Assert.Null(reader.GetNextEntry());
+ }
+
+ [Theory]
+ [MemberData(nameof(GetInvalidTarEntryFormats))]
+ public void CreateFromDirectory_InvalidFormat_Throws(TarEntryFormat format)
+ {
+ using TempDirectory source = new TempDirectory();
+ using MemoryStream archive = new MemoryStream();
+
+ Assert.Throws("format", () =>
+ TarFile.CreateFromDirectory(source.Path, archive, includeBaseDirectory: false, format));
+ }
}
}
diff --git a/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.CreateFromDirectoryAsync.File.Tests.cs b/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.CreateFromDirectoryAsync.File.Tests.cs
index 0aa50a9ed71fb4..541976de84e507 100644
--- a/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.CreateFromDirectoryAsync.File.Tests.cs
+++ b/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.CreateFromDirectoryAsync.File.Tests.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
@@ -297,5 +297,45 @@ public async Task SkipRecursionIntoBaseDirectorySymlinkAsync()
Assert.Null(await reader.GetNextEntryAsync()); // subDirectory should not be found
}
+
+ [Theory]
+ [MemberData(nameof(GetTarEntryFormats))]
+ public async Task CreateFromDirectoryAsync_WithFormat(TarEntryFormat format)
+ {
+ using (TempDirectory source = new TempDirectory())
+ using (TempDirectory destination = new TempDirectory())
+ {
+ string fileName = "file.txt";
+ File.Create(Path.Join(source.Path, fileName)).Dispose();
+
+ string destinationArchiveFileName = Path.Join(destination.Path, "output.tar");
+ await TarFile.CreateFromDirectoryAsync(source.Path, destinationArchiveFileName, includeBaseDirectory: false, format);
+
+ await using (FileStream fileStream = File.OpenRead(destinationArchiveFileName))
+ await using (TarReader reader = new TarReader(fileStream))
+ {
+ TarEntry entry = await reader.GetNextEntryAsync();
+ Assert.NotNull(entry);
+ Assert.Equal(format, entry.Format);
+ Assert.Equal(fileName, entry.Name);
+
+ Assert.Null(await reader.GetNextEntryAsync());
+ }
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(GetInvalidTarEntryFormats))]
+ public async Task CreateFromDirectoryAsync_InvalidFormat_Throws(TarEntryFormat format)
+ {
+ using (TempDirectory source = new TempDirectory())
+ using (TempDirectory destination = new TempDirectory())
+ {
+ string destinationArchiveFileName = Path.Join(destination.Path, "output.tar");
+
+ await Assert.ThrowsAsync("format", () =>
+ TarFile.CreateFromDirectoryAsync(source.Path, destinationArchiveFileName, includeBaseDirectory: false, format));
+ }
+ }
}
}
diff --git a/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.CreateFromDirectoryAsync.Stream.Tests.cs b/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.CreateFromDirectoryAsync.Stream.Tests.cs
index 8dbde4461290a6..9ce4caece94a7e 100644
--- a/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.CreateFromDirectoryAsync.Stream.Tests.cs
+++ b/src/libraries/System.Formats.Tar/tests/TarFile/TarFile.CreateFromDirectoryAsync.Stream.Tests.cs
@@ -66,5 +66,46 @@ public async Task NonExistentDirectory_Throws_Async()
}
}
}
+
+ [Theory]
+ [MemberData(nameof(GetTarEntryFormats))]
+ public async Task CreateFromDirectoryAsync_WithFormat(TarEntryFormat format)
+ {
+ using (TempDirectory source = new TempDirectory())
+ {
+ string fileName = "file.txt";
+ File.Create(Path.Join(source.Path, fileName)).Dispose();
+
+ await using (MemoryStream archive = new MemoryStream())
+ {
+ await TarFile.CreateFromDirectoryAsync(source.Path, archive, includeBaseDirectory: false, format);
+
+ archive.Position = 0;
+ await using (TarReader reader = new TarReader(archive))
+ {
+ TarEntry entry = await reader.GetNextEntryAsync();
+ Assert.NotNull(entry);
+ Assert.Equal(format, entry.Format);
+ Assert.Equal(fileName, entry.Name);
+
+ Assert.Null(await reader.GetNextEntryAsync());
+ }
+ }
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(GetInvalidTarEntryFormats))]
+ public async Task CreateFromDirectoryAsync_InvalidFormat_Throws(TarEntryFormat format)
+ {
+ using (TempDirectory source = new TempDirectory())
+ {
+ await using (MemoryStream archive = new MemoryStream())
+ {
+ await Assert.ThrowsAsync("format", () =>
+ TarFile.CreateFromDirectoryAsync(source.Path, archive, includeBaseDirectory: false, format));
+ }
+ }
+ }
}
}
diff --git a/src/libraries/System.Formats.Tar/tests/TarTestsBase.cs b/src/libraries/System.Formats.Tar/tests/TarTestsBase.cs
index 606277b02b28b7..caa8c6f053a42b 100644
--- a/src/libraries/System.Formats.Tar/tests/TarTestsBase.cs
+++ b/src/libraries/System.Formats.Tar/tests/TarTestsBase.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
@@ -560,6 +560,22 @@ public static IEnumerable