using LibHac.Common;
using LibHac.Fs;
using LibHac.Util;
using Xunit;

namespace LibHac.Tests.Fs
{
    public class PathToolTests
    {
        [Theory]
        [MemberData(nameof(NormalizeTestItems))]
        public static void Normalize(string path, bool preserveUnc, bool hasMountName, string expectedNormalized,
            long expectedLength, Result expectedResult)
        {
            var buffer = new byte[0x301];

            Result result = PathTool.Normalize(buffer, out long normalizedLength, path.ToU8Span(), preserveUnc,
                hasMountName);

            Assert.Equal(expectedResult, result);
            Assert.Equal(expectedNormalized, StringUtils.Utf8ZToString(buffer));
            Assert.Equal(expectedLength, normalizedLength);
        }

        [Theory]
        [MemberData(nameof(IsNormalizedTestItems))]
        public static void IsNormalized(string path, bool preserveUnc, bool hasMountName, bool expectedIsNormalized,
            Result expectedResult)
        {
            Result result = PathTool.IsNormalized(out bool isNormalized, path.ToU8Span(), preserveUnc, hasMountName);

            Assert.Equal(expectedResult, result);

            if (result.IsSuccess())
            {
                Assert.Equal(expectedIsNormalized, isNormalized);
            }
        }

        [Theory]
        [MemberData(nameof(SubpathTestItems))]
        public static void IsSubpath(string path1, string path2, bool expectedResult)
        {
            bool result = PathTool.IsSubpath(path1.ToU8Span(), path2.ToU8Span());

            Assert.Equal(expectedResult, result);
        }

        public static object[][] NormalizeTestItems =
        {
            new object[] {@"", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"/", false, false, @"/", 1, Result.Success},
            new object[] {@"/.", false, false, @"/", 1, Result.Success},
            new object[] {@"/a/b/c", false, false, @"/a/b/c", 6, Result.Success},
            new object[] {@"/a/b/../c", false, false, @"/a/c", 4, Result.Success},
            new object[] {@"/a/b/c/..", false, false, @"/a/b", 4, Result.Success},
            new object[] {@"/a/b/c/.", false, false, @"/a/b/c", 6, Result.Success},
            new object[] {@"/a/../../..", false, false, @"/a/", 0, ResultFs.DirectoryUnobtainable.Value},
            new object[] {@"/a/../../../a/b/c", false, false, @"/a/", 0, ResultFs.DirectoryUnobtainable.Value},
            new object[] {@"//a/b//.//c", false, false, @"/a/b/c", 6, Result.Success},
            new object[] {@"/../a/b/c/.", false, false, @"/", 0, ResultFs.DirectoryUnobtainable.Value},
            new object[] {@"/./aaa/bbb/ccc/.", false, false, @"/aaa/bbb/ccc", 12, Result.Success},
            new object[] {@"/a/b/c/", false, false, @"/a/b/c", 6, Result.Success},
            new object[] {@"a/b/c/", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"/aa/./bb/../cc/", false, false, @"/aa/cc", 6, Result.Success},
            new object[] {@"/./b/../c/", false, false, @"/c", 2, Result.Success},
            new object[] {@"/a/../../../", false, false, @"/a/", 0, ResultFs.DirectoryUnobtainable.Value},
            new object[] {@"//a/b//.//c/", false, false, @"/a/b/c", 6, Result.Success},
            new object[] {@"/tmp/../", false, false, @"/", 1, Result.Success},
            new object[] {@"a", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"a/../../../a/b/c", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"./b/../c/", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@".", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"../a/b/c/.", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"./a/b/c/.", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"abc", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:/a/b/../c", false, true, @"mount:/a/c", 10, Result.Success},
            new object[] {@"mount:/a/b/../c", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"a:/a/b/c", false, true, @"a:/a/b/c", 8, Result.Success},
            new object[] {@"mount:/a/b/../c", false, true, @"mount:/a/c", 10, Result.Success},
            new object[] {@"mount:\a/b/../c", false, true, @"mount:\a/c", 10, Result.Success},
            new object[] {@"mount:\a/b\../c", false, true, @"mount:/a/c", 10, Result.Success},
            new object[] {@"mount:\a/b/c", false, true, @"mount:\a/b/c", 12, Result.Success},
            new object[] {@"mount:/a\../b\..c", false, true, @"mount:/b\..c", 12, Result.Success},
            new object[] {@"mount:/a\../b/..cd", false, true, @"mount:/b/..cd", 13, Result.Success},
            new object[] {@"mount:/a\..d/b/c\..", false, true, @"mount:/a\..d/b", 14, Result.Success},
            new object[] {@"mount:", false, true, @"mount:/", 7, Result.Success},
            new object[] {@"abc:/a/../../../a/b/c", false, true, @"abc:/a/", 0, ResultFs.DirectoryUnobtainable.Value},
            new object[] {@"abc:/./b/../c/", false, true, @"abc:/c", 6, Result.Success},
            new object[] {@"abc:/.", false, true, @"abc:/", 5, Result.Success},
            new object[] {@"abc:/..", false, true, @"abc:/", 0, ResultFs.DirectoryUnobtainable.Value},
            new object[] {@"abc:/", false, true, @"abc:/", 5, Result.Success},
            new object[] {@"abc://a/b//.//c", false, true, @"abc:/a/b/c", 10, Result.Success},
            new object[] {@"abc:/././/././a/b//.//c", false, true, @"abc:/a/b/c", 10, Result.Success},
            new object[] {@"mount:/d./aa", false, true, @"mount:/d./aa", 12, Result.Success},
            new object[] {@"mount:/d/..", false, true, @"mount:/", 7, Result.Success},
            new object[] {@"/path/aaa/bbb\..\h/ddd", false, false, @"/path/aaa/h/ddd", 15, Result.Success},
            new object[] {@"/path/aaa/bbb/../h/ddd", false, false, @"/path/aaa/h/ddd", 15, Result.Success},
            new object[] {@"/path/aaa/bbb\.\h/ddd", false, false, @"/path/aaa/bbb\.\h/ddd", 21, Result.Success},
            new object[] {@"/path/aaa/bbb\./h/ddd", false, false, @"/path/aaa/bbb\./h/ddd", 21, Result.Success},
            new object[] {@"/path/aaa/bbb/./h/ddd", false, false, @"/path/aaa/bbb/h/ddd", 19, Result.Success},
            new object[] {@"mount:abcd", false, true, @"mount:abcd", 10, Result.Success},
            new object[] {@"mount:", false, true, @"mount:/", 7, Result.Success},
            new object[] {@"mount:/", false, true, @"mount:/", 7, Result.Success},
            new object[] {@"mount:\..", false, true, @"mount:/", 0, ResultFs.DirectoryUnobtainable.Value},
            new object[] {@"mount:/a/b\..", false, true, @"mount:/a", 8, Result.Success},
            new object[] {@"mount:/dir", false, true, @"mount:/dir", 10, Result.Success},
            new object[] {@"mount:/dir/", false, true, @"mount:/dir", 10, Result.Success},
            new object[] {@"mount:\", false, true, @"mount:\", 7, Result.Success},
            new object[] {@"mo.unt:\", false, true, @"", 0, ResultFs.InvalidCharacter.Value},
            new object[] {@"mount.:\", false, true, @"", 0, ResultFs.InvalidCharacter.Value},
            new object[] {@"mount:./aa/bb", false, true, @"mount:aa/bb", 11, Result.Success},
            new object[] {@"mount:.../aa/bb", false, true, @"mount:.../aa/bb", 15, Result.Success},
            new object[] {@"mount:...aa/bb", false, true, @"mount:...aa/bb", 14, Result.Success},
            new object[] {@"...aa/bb", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount01234567890/aa/bb", false, true, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount01234567890:/aa/bb", false, true, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount0123456789:/aa/bb", false, true, @"mount0123456789:/aa/bb", 22, Result.Success},
            new object[] {@"mount012345678:/aa/bb", false, true, @"mount012345678:/aa/bb", 21, Result.Success},
            new object[] {@"mount:aa/..\bb", false, true, @"mount:aa/..\bb", 14, Result.Success},
            new object[] {@"mount:..\bb", false, true, @"mount:..\bb", 11, Result.Success},
            new object[] {@"mount:/..\bb", false, true, @"mount:/", 0, ResultFs.DirectoryUnobtainable.Value},
            new object[] {@"mount:/.\bb", false, true, @"mount:/.\bb", 11, Result.Success},
            new object[] {@"mount:\..\bb", false, true, @"mount:/", 0, ResultFs.DirectoryUnobtainable.Value},
            new object[] {@"mount:\.\bb", false, true, @"mount:\.\bb", 11, Result.Success},
            new object[] {@"mount:/a\..\bb", false, true, @"mount:/bb", 9, Result.Success},
            new object[] {@"mount:/a\.\bb", false, true, @"mount:/a\.\bb", 13, Result.Success},
            new object[] {@"//$abc/bb", false, false, @"/$abc/bb", 8, Result.Success},
            new object[] {@"//:abc/bb", false, false, @"/:abc/bb", 8, Result.Success},
            new object[] {@"\\\asd", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\/asd", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\//asd", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"//", false, false, @"/", 1, Result.Success},
            new object[] {@"///..", false, false, @"/", 0, ResultFs.DirectoryUnobtainable.Value},
            new object[] {@"\\a/b/cc/../d", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/b/cc/../d/..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/b/cc/../d/../..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/b/cc/../d/../../..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"c:/aa/bb", false, true, @"c:/aa/bb", 8, Result.Success},
            new object[] {@"c:/aa/bb/..", false, true, @"c:/aa", 5, Result.Success},
            new object[] {@"c:/aa/bb/../..", false, true, @"c:/", 3, Result.Success},
            new object[] {@"c:/aa/bb/../../..", false, true, @"c:/aa/bb/", 0, ResultFs.DirectoryUnobtainable.Value},
            new object[] {@"mount:\c:/aa", false, true, @"mount:\c:/aa", 12, Result.Success},
            new object[] {@"mount:\c:/aa/..", false, true, @"mount:\c:", 9, Result.Success},
            new object[] {@"mount:\c:/aa/../..", false, true, @"mount:/", 7, Result.Success},
            new object[] {@"mount:\c:/aa/../../..", false, true, @"mount:/c:/aa/", 0, ResultFs.DirectoryUnobtainable.Value},
            new object[] {@"mount:/c:\aa/bb", false, true, @"mount:/c:\aa/bb", 15, Result.Success},
            new object[] {@"mount:/c:\aa/bb/..", false, true, @"mount:/c:\aa", 12, Result.Success},
            new object[] {@"mount:/c:\aa/bb/../..", false, true, @"mount:/", 7, Result.Success},
            new object[] {@"mount:/c:\aa/bb/../../..", false, true, @"mount:/c:\aa/bb/", 0, ResultFs.DirectoryUnobtainable.Value},
            new object[] {@"mount:////c:\aa/bb", false, true, @"mount:/c:\aa/bb", 15, Result.Success},
            new object[] {@"mount:////c:\aa/bb/..", false, true, @"mount:/c:\aa", 12, Result.Success},
            new object[] {@"mount:////c:\aa/bb/../..", false, true, @"mount:/", 7, Result.Success},
            new object[] {@"mount:////c:\aa/bb/../../..", false, true, @"mount:/c:\aa/bb/", 0, ResultFs.DirectoryUnobtainable.Value},
            new object[] {@"mount:/\aa/bb", false, true, @"mount:/\aa/bb", 13, Result.Success},
            new object[] {@"mount:/\aa/bb/..", false, true, @"mount:/\aa", 10, Result.Success},
            new object[] {@"mount:/\aa/bb/../..", false, true, @"mount:/", 7, Result.Success},
            new object[] {@"mount:/\aa/bb/../../..", false, true, @"mount:/\aa/bb/", 0, ResultFs.DirectoryUnobtainable.Value},
            new object[] {@"mount:/c:/aa/bb", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:c:/aa/bb", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:c:/aa/bb", false, true, @"mount:c:/aa/bb", 14, Result.Success},
            new object[] {@"mount:/\aa/../b", false, true, @"mount:/b", 8, Result.Success},
            new object[] {@"mount:/\aa/../b/..", false, true, @"mount:/", 7, Result.Success},
            new object[] {@"mount:/\aa/../b/../..", false, true, @"mount:/b/a/", 0, ResultFs.DirectoryUnobtainable.Value},
            new object[] {@"mount://aa/bb", false, true, @"mount:/aa/bb", 12, Result.Success},
            new object[] {@"mount://aa/bb/..", false, true, @"mount:/aa", 9, Result.Success},
            new object[] {@"//aa/bb", false, true, @"/aa/bb", 6, Result.Success},
            new object[] {@"//aa/bb/..", false, true, @"/aa", 3, Result.Success},
            new object[] {@"//aa/bb", false, false, @"/aa/bb", 6, Result.Success},
            new object[] {@"//aa/bb/..", false, false, @"/aa", 3, Result.Success},
            new object[] {@"/aa/bb", false, false, @"/aa/bb", 6, Result.Success},
            new object[] {@"/aa/bb/..", false, false, @"/aa", 3, Result.Success},
            new object[] {@"/aa/bb/../..", false, false, @"/", 1, Result.Success},
            new object[] {@"/aa/bb/../../..", false, false, @"/aa/bb/", 0, ResultFs.DirectoryUnobtainable.Value},
            new object[] {@"c:/aa", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"c:/aa/..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"c:/aa/../..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"c:abcde/aa/bb", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"c:abcde/aa/bb/..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"c:abcde/aa/bb/../..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"c:abcde/aa/bb/../../..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"c:abcde", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"c:abcde/..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"c:abcde/", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"///aa", false, false, @"/aa", 3, Result.Success},
            new object[] {@"//aa//bb", false, false, @"/aa/bb", 6, Result.Success},
            new object[] {@"//aa//bb/..", false, false, @"/aa", 3, Result.Success},
            new object[] {@"//./bb", false, false, @"/bb", 3, Result.Success},
            new object[] {@"//../bb", false, false, @"/", 0, ResultFs.DirectoryUnobtainable.Value},
            new object[] {@"//.../bb", false, false, @"/.../bb", 7, Result.Success},
            new object[] {@"//aa$abc/bb", false, false, @"/aa$abc/bb", 10, Result.Success},
            new object[] {@"//aa$/bb", false, false, @"/aa$/bb", 7, Result.Success},
            new object[] {@"//aa:/bb", false, false, @"/aa:/bb", 7, Result.Success},
            new object[] {@"//aa/bb$b/cc$", false, false, @"/aa/bb$b/cc$", 12, Result.Success},
            new object[] {@"//aa/bb/cc$c", false, false, @"/aa/bb/cc$c", 11, Result.Success},
            new object[] {@"//aa/bb/cc$c/..", false, false, @"/aa/bb", 6, Result.Success},
            new object[] {@"//aa/bb/cc$c/dd", false, false, @"/aa/bb/cc$c/dd", 14, Result.Success},
            new object[] {@"//aa/bb", false, false, @"/aa/bb", 6, Result.Success},
            new object[] {@"//aa/bb/cc//dd", false, false, @"/aa/bb/cc/dd", 12, Result.Success},
            new object[] {@"//aa/bb/cc//dd/..", false, false, @"/aa/bb/cc", 9, Result.Success},
            new object[] {@"//aa/bb/cc//dd/../..", false, false, @"/aa/bb", 6, Result.Success},
            new object[] {@"//aa/bb/cc//dd/../../..", false, false, @"/aa", 3, Result.Success},
            new object[] {@"//aa/bb/cc\/dd", false, false, @"/aa/bb/cc\/dd", 13, Result.Success},
            new object[] {@"//aa/bb/cc//dd", false, false, @"/aa/bb/cc/dd", 12, Result.Success},
            new object[] {@"//aa/bb/cc/dd", false, false, @"/aa/bb/cc/dd", 12, Result.Success},
            new object[] {@"//aa/bb/cc/dd/..", false, false, @"/aa/bb/cc", 9, Result.Success},
            new object[] {@"//aa/bb/cc/dd/../..", false, false, @"/aa/bb", 6, Result.Success},
            new object[] {@"//aa/bb/cc/dd/../../..", false, false, @"/aa", 3, Result.Success},
            new object[] {@"//aa/bb/cc/\dd", false, false, @"/aa/bb/cc/\dd", 13, Result.Success},
            new object[] {@"//aa/bb/cc/\dd/..", false, false, @"/aa/bb/cc", 9, Result.Success},
            new object[] {@"//aa/bb/cc/\dd/../..", false, false, @"/aa/bb", 6, Result.Success},
            new object[] {@"//aa/bb/cc/\dd/../../..", false, false, @"/aa", 3, Result.Success},
            new object[] {@"//aa/../", false, false, @"/", 1, Result.Success},
            new object[] {@"//aa//", false, false, @"/aa", 3, Result.Success},
            new object[] {@"//aa/bb..", false, false, @"/aa/bb..", 8, Result.Success},
            new object[] {@"//aa/bb../..", false, false, @"/aa", 3, Result.Success},
            new object[] {@"//aa/bb../", false, false, @"/aa/bb..", 8, Result.Success},
            new object[] {@"//aa/bb..//..", false, false, @"/aa", 3, Result.Success},
            new object[] {@"/\\aa/bb/cc/..", false, true, @"/\\aa/bb", 8, Result.Success},
            new object[] {@"/\\aa/bb/cc/../..", false, true, @"/\\aa", 5, Result.Success},
            new object[] {@"/\\aa/bb/cc/../../..", false, true, @"/", 1, Result.Success},
            new object[] {@"/\\aa/bb/cc/../../../..", false, true, @"/\\aa/bb/cc/", 0, ResultFs.DirectoryUnobtainable.Value},
            new object[] {@"c:aa\bb/cc", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"c:aa\bb/cc/..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"c:aa\bb/cc/../..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"c:aa\bb/cc/../../..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"c:\//\aa\bb", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"c:\//\aa\bb/..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount://////a/bb/c", false, true, @"mount:/a/bb/c", 13, Result.Success},
            new object[] {@"mount://////a/bb/c/..", false, true, @"mount:/a/bb", 11, Result.Success},
            new object[] {@"mount://////a/bb/c/../..", false, true, @"mount:/a", 8, Result.Success},
            new object[] {@"//", false, false, @"/", 1, Result.Success},
            new object[] {@"///..", false, false, @"/", 0, ResultFs.DirectoryUnobtainable.Value},
            new object[] {@"//a", false, false, @"/a", 2, Result.Success},
            new object[] {@"//a/..", false, false, @"/", 1, Result.Success},
            new object[] {@"//a", false, false, @"/a", 2, Result.Success},
            new object[] {@"//a/..", false, false, @"/", 1, Result.Success},
            new object[] {@"//a/", false, false, @"/a", 2, Result.Success},
            new object[] {@"//a//..", false, false, @"/", 1, Result.Success},
            new object[] {@"//a/b", false, false, @"/a/b", 4, Result.Success},
            new object[] {@"//a/b/..", false, false, @"/a", 2, Result.Success},
            new object[] {@"//a/b/", false, false, @"/a/b", 4, Result.Success},
            new object[] {@"//a/b//..", false, false, @"/a", 2, Result.Success},
            new object[] {@"//a/b/c", false, false, @"/a/b/c", 6, Result.Success},
            new object[] {@"//a/b/c/..", false, false, @"/a/b", 4, Result.Success},
            new object[] {@"//a/b/c/../..", false, false, @"/a", 2, Result.Success},
            new object[] {@"//a/b/c/", false, false, @"/a/b/c", 6, Result.Success},
            new object[] {@"//a/b/c//..", false, false, @"/a/b", 4, Result.Success},
            new object[] {@"//a/b/c//../..", false, false, @"/a", 2, Result.Success},
            new object[] {@"\\", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\/..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a//..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/b", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/b/..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/b/", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/b//..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/b/c", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/b/c/..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/b/c/../..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/b/c/", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/b/c//..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/b/c//../..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\/..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a\", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a\/..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a\b", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a\b/..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a\b\", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a\b\/..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a\b\c", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a\b\c/..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a\b\c/../..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a\b\c\", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a\b\c\/..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a\b\c\/../..", false, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"//$abc/bb", true, false, @"", 0, ResultFs.InvalidCharacter.Value},
            new object[] {@"//:abc/bb", true, false, @"", 0, ResultFs.InvalidCharacter.Value},
            new object[] {@"\\\asd", true, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\/asd", true, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\//asd", true, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"//", true, false, @"/", 1, Result.Success},
            new object[] {@"///..", true, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/b/cc/../d", true, false, @"\\a/b/d", 7, Result.Success},
            new object[] {@"\\a/b/cc/../d/..", true, false, @"\\a/b", 5, Result.Success},
            new object[] {@"\\a/b/cc/../d/../..", true, false, @"\\a/b", 5, Result.Success},
            new object[] {@"\\a/b/cc/../d/../../..", true, false, @"\\a/b", 5, Result.Success},
            new object[] {@"c:/aa/bb", true, true, @"c:/aa/bb", 8, Result.Success},
            new object[] {@"c:/aa/bb/..", true, true, @"c:/aa", 5, Result.Success},
            new object[] {@"c:/aa/bb/../..", true, true, @"c:/", 3, Result.Success},
            new object[] {@"c:/aa/bb/../../..", true, true, @"c:/aa/bb/", 0, ResultFs.DirectoryUnobtainable.Value},
            new object[] {@"mount:\c:/aa", true, true, @"mount:\c:/aa", 12, Result.Success},
            new object[] {@"mount:\c:/aa/..", true, true, @"mount:\c:", 9, Result.Success},
            new object[] {@"mount:\c:/aa/../..", true, true, @"mount:/", 7, Result.Success},
            new object[] {@"mount:\c:/aa/../../..", true, true, @"mount:/c:/aa/", 0, ResultFs.DirectoryUnobtainable.Value},
            new object[] {@"mount:/c:\aa/bb", true, true, @"mount:/c:\aa/bb", 15, Result.Success},
            new object[] {@"mount:/c:\aa/bb/..", true, true, @"mount:/c:\aa", 12, Result.Success},
            new object[] {@"mount:/c:\aa/bb/../..", true, true, @"mount:/c:", 9, Result.Success},
            new object[] {@"mount:/c:\aa/bb/../../..", true, true, @"mount:/c:", 9, Result.Success},
            new object[] {@"mount:////c:\aa/bb", true, true, @"mount:////c:\aa/bb", 18, Result.Success},
            new object[] {@"mount:////c:\aa/bb/..", true, true, @"mount:////c:\aa", 15, Result.Success},
            new object[] {@"mount:////c:\aa/bb/../..", true, true, @"mount:////c:", 12, Result.Success},
            new object[] {@"mount:////c:\aa/bb/../../..", true, true, @"mount:////c:", 12, Result.Success},
            new object[] {@"mount:/\aa/bb", true, true, @"mount:/\aa/bb", 13, Result.Success},
            new object[] {@"mount:/\aa/bb/..", true, true, @"mount:/\aa", 10, Result.Success},
            new object[] {@"mount:/\aa/bb/../..", true, true, @"mount:/", 7, Result.Success},
            new object[] {@"mount:/\aa/bb/../../..", true, true, @"mount:/\aa/bb/", 0, ResultFs.DirectoryUnobtainable.Value},
            new object[] {@"mount:/c:/aa/bb", true, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:c:/aa/bb", true, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:c:/aa/bb", true, true, @"mount:c:/aa/bb", 14, Result.Success},
            new object[] {@"mount:/\aa/../b", true, true, @"mount:/b", 8, Result.Success},
            new object[] {@"mount:/\aa/../b/..", true, true, @"mount:/", 7, Result.Success},
            new object[] {@"mount:/\aa/../b/../..", true, true, @"mount:/b/a/", 0, ResultFs.DirectoryUnobtainable.Value},
            new object[] {@"mount://aa/bb", true, true, @"mount:/\\aa/bb", 14, Result.Success},
            new object[] {@"mount://aa/bb/..", true, true, @"mount:/\\aa/bb", 14, Result.Success},
            new object[] {@"//aa/bb", true, true, @"/\\aa/bb", 8, Result.Success},
            new object[] {@"//aa/bb/..", true, true, @"/\\aa/bb", 8, Result.Success},
            new object[] {@"//aa/bb", true, false, @"\\aa/bb", 7, Result.Success},
            new object[] {@"//aa/bb/..", true, false, @"\\aa/bb", 7, Result.Success},
            new object[] {@"/aa/bb", true, false, @"/aa/bb", 6, Result.Success},
            new object[] {@"/aa/bb/..", true, false, @"/aa", 3, Result.Success},
            new object[] {@"/aa/bb/../..", true, false, @"/", 1, Result.Success},
            new object[] {@"/aa/bb/../../..", true, false, @"/aa/bb/", 0, ResultFs.DirectoryUnobtainable.Value},
            new object[] {@"c:/aa", true, false, @"c:/aa", 5, Result.Success},
            new object[] {@"c:/aa/..", true, false, @"c:", 2, Result.Success},
            new object[] {@"c:/aa/../..", true, false, @"c:", 2, Result.Success},
            new object[] {@"c:abcde/aa/bb", true, false, @"c:abcde/aa/bb", 13, Result.Success},
            new object[] {@"c:abcde/aa/bb/..", true, false, @"c:abcde/aa", 10, Result.Success},
            new object[] {@"c:abcde/aa/bb/../..", true, false, @"c:abcde", 7, Result.Success},
            new object[] {@"c:abcde/aa/bb/../../..", true, false, @"c:abcde", 7, Result.Success},
            new object[] {@"c:abcde", true, false, @"c:abcde", 7, Result.Success},
            new object[] {@"c:abcde/..", true, false, @"c:abcde", 7, Result.Success},
            new object[] {@"c:abcde/", true, false, @"c:abcde", 7, Result.Success},
            new object[] {@"///aa", true, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"//aa//bb", true, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"//aa//bb/..", true, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"//./bb", true, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"//../bb", true, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"//.../bb", true, false, @"\\.../bb", 8, Result.Success},
            new object[] {@"//aa$abc/bb", true, false, @"", 0, ResultFs.InvalidCharacter.Value},
            new object[] {@"//aa$/bb", true, false, @"", 0, ResultFs.InvalidCharacter.Value},
            new object[] {@"//aa:/bb", true, false, @"", 0, ResultFs.InvalidCharacter.Value},
            new object[] {@"//aa/bb$b/cc$", true, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"//aa/bb/cc$c", true, false, @"\\aa/bb/cc$c", 12, Result.Success},
            new object[] {@"//aa/bb/cc$c/..", true, false, @"\\aa/bb", 7, Result.Success},
            new object[] {@"//aa/bb/cc$c/dd", true, false, @"\\aa/bb/cc$c/dd", 15, Result.Success},
            new object[] {@"//aa/bb", true, false, @"\\aa/bb", 7, Result.Success},
            new object[] {@"//aa/bb/cc//dd", true, false, @"\\aa/bb/cc/dd", 13, Result.Success},
            new object[] {@"//aa/bb/cc//dd/..", true, false, @"\\aa/bb/cc", 10, Result.Success},
            new object[] {@"//aa/bb/cc//dd/../..", true, false, @"\\aa/bb", 7, Result.Success},
            new object[] {@"//aa/bb/cc//dd/../../..", true, false, @"\\aa/bb", 7, Result.Success},
            new object[] {@"//aa/bb/cc\/dd", true, false, @"\\aa/bb/cc\/dd", 14, Result.Success},
            new object[] {@"//aa/bb/cc//dd", true, false, @"\\aa/bb/cc/dd", 13, Result.Success},
            new object[] {@"//aa/bb/cc/dd", true, false, @"\\aa/bb/cc/dd", 13, Result.Success},
            new object[] {@"//aa/bb/cc/dd/..", true, false, @"\\aa/bb/cc", 10, Result.Success},
            new object[] {@"//aa/bb/cc/dd/../..", true, false, @"\\aa/bb", 7, Result.Success},
            new object[] {@"//aa/bb/cc/dd/../../..", true, false, @"\\aa/bb", 7, Result.Success},
            new object[] {@"//aa/bb/cc/\dd", true, false, @"\\aa/bb/cc/\dd", 14, Result.Success},
            new object[] {@"//aa/bb/cc/\dd/..", true, false, @"\\aa/bb/cc", 10, Result.Success},
            new object[] {@"//aa/bb/cc/\dd/../..", true, false, @"\\aa/bb", 7, Result.Success},
            new object[] {@"//aa/bb/cc/\dd/../../..", true, false, @"\\aa/bb", 7, Result.Success},
            new object[] {@"//aa/../", true, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"//aa//", true, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"//aa/bb..", true, false, @"\\aa/bb..", 9, Result.Success},
            new object[] {@"//aa/bb../..", true, false, @"\\aa/bb..", 9, Result.Success},
            new object[] {@"//aa/bb../", true, false, @"\\aa/bb..", 9, Result.Success},
            new object[] {@"//aa/bb..//..", true, false, @"\\aa/bb..", 9, Result.Success},
            new object[] {@"/\\aa/bb/cc/..", true, true, @"/\\aa/bb", 8, Result.Success},
            new object[] {@"/\\aa/bb/cc/../..", true, true, @"/\\aa/bb", 8, Result.Success},
            new object[] {@"/\\aa/bb/cc/../../..", true, true, @"/\\aa/bb", 8, Result.Success},
            new object[] {@"/\\aa/bb/cc/../../../..", true, true, @"/\\aa/bb", 8, Result.Success},
            new object[] {@"c:aa\bb/cc", true, false, @"c:aa\bb/cc", 10, Result.Success},
            new object[] {@"c:aa\bb/cc/..", true, false, @"c:aa\bb", 7, Result.Success},
            new object[] {@"c:aa\bb/cc/../..", true, false, @"c:aa", 4, Result.Success},
            new object[] {@"c:aa\bb/cc/../../..", true, false, @"c:aa", 4, Result.Success},
            new object[] {@"c:\//\aa\bb", true, false, @"c:\/\aa\bb", 10, Result.Success},
            new object[] {@"c:\//\aa\bb/..", true, false, @"c:\", 3, Result.Success},
            new object[] {@"mount://////a/bb/c", true, true, @"mount:/\\a/bb/c", 15, Result.Success},
            new object[] {@"mount://////a/bb/c/..", true, true, @"mount:/\\a/bb", 13, Result.Success},
            new object[] {@"mount://////a/bb/c/../..", true, true, @"mount:/\\a/bb", 13, Result.Success},
            new object[] {@"//", true, false, @"/", 1, Result.Success},
            new object[] {@"///..", true, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"//a", true, false, @"/a", 2, Result.Success},
            new object[] {@"//a/..", true, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"//a", true, false, @"/a", 2, Result.Success},
            new object[] {@"//a/..", true, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"//a/", true, false, @"\\a/", 4, Result.Success},
            new object[] {@"//a//..", true, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"//a/b", true, false, @"\\a/b", 5, Result.Success},
            new object[] {@"//a/b/..", true, false, @"\\a/b", 5, Result.Success},
            new object[] {@"//a/b/", true, false, @"\\a/b", 5, Result.Success},
            new object[] {@"//a/b//..", true, false, @"\\a/b", 5, Result.Success},
            new object[] {@"//a/b/c", true, false, @"\\a/b/c", 7, Result.Success},
            new object[] {@"//a/b/c/..", true, false, @"\\a/b", 5, Result.Success},
            new object[] {@"//a/b/c/../..", true, false, @"\\a/b", 5, Result.Success},
            new object[] {@"//a/b/c/", true, false, @"\\a/b/c", 7, Result.Success},
            new object[] {@"//a/b/c//..", true, false, @"\\a/b", 5, Result.Success},
            new object[] {@"//a/b/c//../..", true, false, @"\\a/b", 5, Result.Success},
            new object[] {@"\\", true, false, @"\\", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\/..", true, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a", true, false, @"\\", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/..", true, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/", true, false, @"\\a/", 4, Result.Success},
            new object[] {@"\\a//..", true, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/b", true, false, @"\\a/b", 5, Result.Success},
            new object[] {@"\\a/b/..", true, false, @"\\a/b", 5, Result.Success},
            new object[] {@"\\a/b/", true, false, @"\\a/b", 5, Result.Success},
            new object[] {@"\\a/b//..", true, false, @"\\a/b", 5, Result.Success},
            new object[] {@"\\a/b/c", true, false, @"\\a/b/c", 7, Result.Success},
            new object[] {@"\\a/b/c/..", true, false, @"\\a/b", 5, Result.Success},
            new object[] {@"\\a/b/c/../..", true, false, @"\\a/b", 5, Result.Success},
            new object[] {@"\\a/b/c/", true, false, @"\\a/b/c", 7, Result.Success},
            new object[] {@"\\a/b/c//..", true, false, @"\\a/b", 5, Result.Success},
            new object[] {@"\\a/b/c//../..", true, false, @"\\a/b", 5, Result.Success},
            new object[] {@"\\", true, false, @"\\", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\/..", true, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a", true, false, @"\\", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/..", true, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a\", true, false, @"\\a/", 4, Result.Success},
            new object[] {@"\\a\/..", true, false, @"", 0, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a\b", true, false, @"\\a/b", 5, Result.Success},
            new object[] {@"\\a\b/..", true, false, @"\\a/b", 5, Result.Success},
            new object[] {@"\\a\b\", true, false, @"\\a/b\", 6, Result.Success},
            new object[] {@"\\a\b\/..", true, false, @"\\a", 3, Result.Success},
            new object[] {@"\\a\b\c", true, false, @"\\a/b\c", 7, Result.Success},
            new object[] {@"\\a\b\c/..", true, false, @"\\a/b", 5, Result.Success},
            new object[] {@"\\a\b\c/../..", true, false, @"\\a/b", 5, Result.Success},
            new object[] {@"\\a\b\c\", true, false, @"\\a/b\c\", 8, Result.Success},
            new object[] {@"\\a\b\c\/..", true, false, @"\\a/b", 5, Result.Success},
            new object[] {@"\\a\b\c\/../..", true, false, @"\\a/b", 5, Result.Success}
        };

        public static object[][] IsNormalizedTestItems =
        {
            new object[] {@"", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"/", false, false, true, Result.Success},
            new object[] {@"/.", false, false, false, Result.Success},
            new object[] {@"/a/b/c", false, false, true, Result.Success},
            new object[] {@"/a/b/../c", false, false, false, Result.Success},
            new object[] {@"/a/b/c/..", false, false, false, Result.Success},
            new object[] {@"/a/b/c/.", false, false, false, Result.Success},
            new object[] {@"/a/../../..", false, false, false, Result.Success},
            new object[] {@"/a/../../../a/b/c", false, false, false, Result.Success},
            new object[] {@"//a/b//.//c", false, false, false, Result.Success},
            new object[] {@"/../a/b/c/.", false, false, false, Result.Success},
            new object[] {@"/./aaa/bbb/ccc/.", false, false, false, Result.Success},
            new object[] {@"/a/b/c/", false, false, false, Result.Success},
            new object[] {@"a/b/c/", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"/aa/./bb/../cc/", false, false, false, Result.Success},
            new object[] {@"/./b/../c/", false, false, false, Result.Success},
            new object[] {@"/a/../../../", false, false, false, Result.Success},
            new object[] {@"//a/b//.//c/", false, false, false, Result.Success},
            new object[] {@"/tmp/../", false, false, false, Result.Success},
            new object[] {@"a", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"a/../../../a/b/c", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"./b/../c/", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@".", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"../a/b/c/.", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"./a/b/c/.", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"abc", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:/a/b/../c", false, true, false, Result.Success},
            new object[] {@"mount:/a/b/../c", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"a:/a/b/c", false, true, true, Result.Success},
            new object[] {@"mount:/a/b/../c", false, true, false, Result.Success},
            new object[] {@"mount:\a/b/../c", false, true, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:\a/b\../c", false, true, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:\a/b/c", false, true, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:/a\../b\..c", false, true, false, Result.Success},
            new object[] {@"mount:/a\../b/..cd", false, true, false, Result.Success},
            new object[] {@"mount:/a\..d/b/c\..", false, true, false, Result.Success},
            new object[] {@"mount:", false, true, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"abc:/a/../../../a/b/c", false, true, false, Result.Success},
            new object[] {@"abc:/./b/../c/", false, true, false, Result.Success},
            new object[] {@"abc:/.", false, true, false, Result.Success},
            new object[] {@"abc:/..", false, true, false, Result.Success},
            new object[] {@"abc:/", false, true, true, Result.Success},
            new object[] {@"abc://a/b//.//c", false, true, false, Result.Success},
            new object[] {@"abc:/././/././a/b//.//c", false, true, false, Result.Success},
            new object[] {@"mount:/d./aa", false, true, true, Result.Success},
            new object[] {@"mount:/d/..", false, true, false, Result.Success},
            new object[] {@"/path/aaa/bbb\..\h/ddd", false, false, false, Result.Success},
            new object[] {@"/path/aaa/bbb/../h/ddd", false, false, false, Result.Success},
            new object[] {@"/path/aaa/bbb\.\h/ddd", false, false, true, Result.Success},
            new object[] {@"/path/aaa/bbb\./h/ddd", false, false, true, Result.Success},
            new object[] {@"/path/aaa/bbb/./h/ddd", false, false, false, Result.Success},
            new object[] {@"mount:abcd", false, true, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:", false, true, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:/", false, true, true, Result.Success},
            new object[] {@"mount:\..", false, true, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:/a/b\..", false, true, false, Result.Success},
            new object[] {@"mount:/dir", false, true, true, Result.Success},
            new object[] {@"mount:/dir/", false, true, false, Result.Success},
            new object[] {@"mount:\", false, true, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mo.unt:\", false, true, false, ResultFs.InvalidCharacter.Value},
            new object[] {@"mount.:\", false, true, false, ResultFs.InvalidCharacter.Value},
            new object[] {@"mount:./aa/bb", false, true, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:.../aa/bb", false, true, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:...aa/bb", false, true, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"...aa/bb", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount01234567890/aa/bb", false, true, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount01234567890:/aa/bb", false, true, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount0123456789:/aa/bb", false, true, true, Result.Success},
            new object[] {@"mount012345678:/aa/bb", false, true, true, Result.Success},
            new object[] {@"mount:aa/..\bb", false, true, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:..\bb", false, true, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:/..\bb", false, true, false, Result.Success},
            new object[] {@"mount:/.\bb", false, true, true, Result.Success},
            new object[] {@"mount:\..\bb", false, true, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:\.\bb", false, true, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:/a\..\bb", false, true, false, Result.Success},
            new object[] {@"mount:/a\.\bb", false, true, true, Result.Success},
            new object[] {@"//$abc/bb", false, false, false, Result.Success},
            new object[] {@"//:abc/bb", false, false, false, Result.Success},
            new object[] {@"\\\asd", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\/asd", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\//asd", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"//", false, false, false, Result.Success},
            new object[] {@"///..", false, false, false, Result.Success},
            new object[] {@"\\a/b/cc/../d", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/b/cc/../d/..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/b/cc/../d/../..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/b/cc/../d/../../..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"c:/aa/bb", false, true, true, Result.Success},
            new object[] {@"c:/aa/bb/..", false, true, false, Result.Success},
            new object[] {@"c:/aa/bb/../..", false, true, false, Result.Success},
            new object[] {@"c:/aa/bb/../../..", false, true, false, Result.Success},
            new object[] {@"mount:\c:/aa", false, true, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:\c:/aa/..", false, true, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:\c:/aa/../..", false, true, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:\c:/aa/../../..", false, true, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:/c:\aa/bb", false, true, true, Result.Success},
            new object[] {@"mount:/c:\aa/bb/..", false, true, false, Result.Success},
            new object[] {@"mount:/c:\aa/bb/../..", false, true, false, Result.Success},
            new object[] {@"mount:/c:\aa/bb/../../..", false, true, false, Result.Success},
            new object[] {@"mount:////c:\aa/bb", false, true, false, Result.Success},
            new object[] {@"mount:////c:\aa/bb/..", false, true, false, Result.Success},
            new object[] {@"mount:////c:\aa/bb/../..", false, true, false, Result.Success},
            new object[] {@"mount:////c:\aa/bb/../../..", false, true, false, Result.Success},
            new object[] {@"mount:/\aa/bb", false, true, true, Result.Success},
            new object[] {@"mount:/\aa/bb/..", false, true, false, Result.Success},
            new object[] {@"mount:/\aa/bb/../..", false, true, false, Result.Success},
            new object[] {@"mount:/\aa/bb/../../..", false, true, false, Result.Success},
            new object[] {@"mount:/c:/aa/bb", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:c:/aa/bb", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:c:/aa/bb", false, true, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:/\aa/../b", false, true, false, Result.Success},
            new object[] {@"mount:/\aa/../b/..", false, true, false, Result.Success},
            new object[] {@"mount:/\aa/../b/../..", false, true, false, Result.Success},
            new object[] {@"mount://aa/bb", false, true, false, Result.Success},
            new object[] {@"mount://aa/bb/..", false, true, false, Result.Success},
            new object[] {@"//aa/bb", false, true, false, Result.Success},
            new object[] {@"//aa/bb/..", false, true, false, Result.Success},
            new object[] {@"//aa/bb", false, false, false, Result.Success},
            new object[] {@"//aa/bb/..", false, false, false, Result.Success},
            new object[] {@"/aa/bb", false, false, true, Result.Success},
            new object[] {@"/aa/bb/..", false, false, false, Result.Success},
            new object[] {@"/aa/bb/../..", false, false, false, Result.Success},
            new object[] {@"/aa/bb/../../..", false, false, false, Result.Success},
            new object[] {@"c:/aa", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"c:/aa/..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"c:/aa/../..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"c:abcde/aa/bb", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"c:abcde/aa/bb/..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"c:abcde/aa/bb/../..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"c:abcde/aa/bb/../../..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"c:abcde", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"c:abcde/..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"c:abcde/", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"///aa", false, false, false, Result.Success},
            new object[] {@"//aa//bb", false, false, false, Result.Success},
            new object[] {@"//aa//bb/..", false, false, false, Result.Success},
            new object[] {@"//./bb", false, false, false, Result.Success},
            new object[] {@"//../bb", false, false, false, Result.Success},
            new object[] {@"//.../bb", false, false, false, Result.Success},
            new object[] {@"//aa$abc/bb", false, false, false, Result.Success},
            new object[] {@"//aa$/bb", false, false, false, Result.Success},
            new object[] {@"//aa:/bb", false, false, false, Result.Success},
            new object[] {@"//aa/bb$b/cc$", false, false, false, Result.Success},
            new object[] {@"//aa/bb/cc$c", false, false, false, Result.Success},
            new object[] {@"//aa/bb/cc$c/..", false, false, false, Result.Success},
            new object[] {@"//aa/bb/cc$c/dd", false, false, false, Result.Success},
            new object[] {@"//aa/bb", false, false, false, Result.Success},
            new object[] {@"//aa/bb/cc//dd", false, false, false, Result.Success},
            new object[] {@"//aa/bb/cc//dd/..", false, false, false, Result.Success},
            new object[] {@"//aa/bb/cc//dd/../..", false, false, false, Result.Success},
            new object[] {@"//aa/bb/cc//dd/../../..", false, false, false, Result.Success},
            new object[] {@"//aa/bb/cc\/dd", false, false, false, Result.Success},
            new object[] {@"//aa/bb/cc//dd", false, false, false, Result.Success},
            new object[] {@"//aa/bb/cc/dd", false, false, false, Result.Success},
            new object[] {@"//aa/bb/cc/dd/..", false, false, false, Result.Success},
            new object[] {@"//aa/bb/cc/dd/../..", false, false, false, Result.Success},
            new object[] {@"//aa/bb/cc/dd/../../..", false, false, false, Result.Success},
            new object[] {@"//aa/bb/cc/\dd", false, false, false, Result.Success},
            new object[] {@"//aa/bb/cc/\dd/..", false, false, false, Result.Success},
            new object[] {@"//aa/bb/cc/\dd/../..", false, false, false, Result.Success},
            new object[] {@"//aa/bb/cc/\dd/../../..", false, false, false, Result.Success},
            new object[] {@"//aa/../", false, false, false, Result.Success},
            new object[] {@"//aa//", false, false, false, Result.Success},
            new object[] {@"//aa/bb..", false, false, false, Result.Success},
            new object[] {@"//aa/bb../..", false, false, false, Result.Success},
            new object[] {@"//aa/bb../", false, false, false, Result.Success},
            new object[] {@"//aa/bb..//..", false, false, false, Result.Success},
            new object[] {@"/\\aa/bb/cc/..", false, true, false, Result.Success},
            new object[] {@"/\\aa/bb/cc/../..", false, true, false, Result.Success},
            new object[] {@"/\\aa/bb/cc/../../..", false, true, false, Result.Success},
            new object[] {@"/\\aa/bb/cc/../../../..", false, true, false, Result.Success},
            new object[] {@"c:aa\bb/cc", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"c:aa\bb/cc/..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"c:aa\bb/cc/../..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"c:aa\bb/cc/../../..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"c:\//\aa\bb", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"c:\//\aa\bb/..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount://////a/bb/c", false, true, false, Result.Success},
            new object[] {@"mount://////a/bb/c/..", false, true, false, Result.Success},
            new object[] {@"mount://////a/bb/c/../..", false, true, false, Result.Success},
            new object[] {@"//", false, false, false, Result.Success},
            new object[] {@"///..", false, false, false, Result.Success},
            new object[] {@"//a", false, false, false, Result.Success},
            new object[] {@"//a/..", false, false, false, Result.Success},
            new object[] {@"//a", false, false, false, Result.Success},
            new object[] {@"//a/..", false, false, false, Result.Success},
            new object[] {@"//a/", false, false, false, Result.Success},
            new object[] {@"//a//..", false, false, false, Result.Success},
            new object[] {@"//a/b", false, false, false, Result.Success},
            new object[] {@"//a/b/..", false, false, false, Result.Success},
            new object[] {@"//a/b/", false, false, false, Result.Success},
            new object[] {@"//a/b//..", false, false, false, Result.Success},
            new object[] {@"//a/b/c", false, false, false, Result.Success},
            new object[] {@"//a/b/c/..", false, false, false, Result.Success},
            new object[] {@"//a/b/c/../..", false, false, false, Result.Success},
            new object[] {@"//a/b/c/", false, false, false, Result.Success},
            new object[] {@"//a/b/c//..", false, false, false, Result.Success},
            new object[] {@"//a/b/c//../..", false, false, false, Result.Success},
            new object[] {@"\\", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\/..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a//..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/b", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/b/..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/b/", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/b//..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/b/c", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/b/c/..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/b/c/../..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/b/c/", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/b/c//..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/b/c//../..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\/..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a\", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a\/..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a\b", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a\b/..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a\b\", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a\b\/..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a\b\c", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a\b\c/..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a\b\c/../..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a\b\c\", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a\b\c\/..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a\b\c\/../..", false, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"//$abc/bb", true, false, false, ResultFs.InvalidCharacter.Value},
            new object[] {@"//:abc/bb", true, false, false, ResultFs.InvalidCharacter.Value},
            new object[] {@"\\\asd", true, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\/asd", true, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\//asd", true, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"//", true, false, false, Result.Success},
            new object[] {@"///..", true, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/b/cc/../d", true, false, false, Result.Success},
            new object[] {@"\\a/b/cc/../d/..", true, false, false, Result.Success},
            new object[] {@"\\a/b/cc/../d/../..", true, false, false, Result.Success},
            new object[] {@"\\a/b/cc/../d/../../..", true, false, false, Result.Success},
            new object[] {@"c:/aa/bb", true, true, true, Result.Success},
            new object[] {@"c:/aa/bb/..", true, true, false, Result.Success},
            new object[] {@"c:/aa/bb/../..", true, true, false, Result.Success},
            new object[] {@"c:/aa/bb/../../..", true, true, false, Result.Success},
            new object[] {@"mount:\c:/aa", true, true, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:\c:/aa/..", true, true, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:\c:/aa/../..", true, true, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:\c:/aa/../../..", true, true, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:/c:\aa/bb", true, true, true, Result.Success},
            new object[] {@"mount:/c:\aa/bb/..", true, true, false, Result.Success},
            new object[] {@"mount:/c:\aa/bb/../..", true, true, false, Result.Success},
            new object[] {@"mount:/c:\aa/bb/../../..", true, true, false, Result.Success},
            new object[] {@"mount:////c:\aa/bb", true, true, false, Result.Success},
            new object[] {@"mount:////c:\aa/bb/..", true, true, false, Result.Success},
            new object[] {@"mount:////c:\aa/bb/../..", true, true, false, Result.Success},
            new object[] {@"mount:////c:\aa/bb/../../..", true, true, false, Result.Success},
            new object[] {@"mount:/\aa/bb", true, true, true, Result.Success},
            new object[] {@"mount:/\aa/bb/..", true, true, false, Result.Success},
            new object[] {@"mount:/\aa/bb/../..", true, true, false, Result.Success},
            new object[] {@"mount:/\aa/bb/../../..", true, true, false, Result.Success},
            new object[] {@"mount:/c:/aa/bb", true, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:c:/aa/bb", true, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:c:/aa/bb", true, true, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"mount:/\aa/../b", true, true, false, Result.Success},
            new object[] {@"mount:/\aa/../b/..", true, true, false, Result.Success},
            new object[] {@"mount:/\aa/../b/../..", true, true, false, Result.Success},
            new object[] {@"mount://aa/bb", true, true, false, Result.Success},
            new object[] {@"mount://aa/bb/..", true, true, false, Result.Success},
            new object[] {@"//aa/bb", true, true, false, Result.Success},
            new object[] {@"//aa/bb/..", true, true, false, Result.Success},
            new object[] {@"//aa/bb", true, false, false, Result.Success},
            new object[] {@"//aa/bb/..", true, false, false, Result.Success},
            new object[] {@"/aa/bb", true, false, true, Result.Success},
            new object[] {@"/aa/bb/..", true, false, false, Result.Success},
            new object[] {@"/aa/bb/../..", true, false, false, Result.Success},
            new object[] {@"/aa/bb/../../..", true, false, false, Result.Success},
            new object[] {@"c:/aa", true, false, true, Result.Success},
            new object[] {@"c:/aa/..", true, false, false, Result.Success},
            new object[] {@"c:/aa/../..", true, false, false, Result.Success},
            new object[] {@"c:abcde/aa/bb", true, false, true, Result.Success},
            new object[] {@"c:abcde/aa/bb/..", true, false, false, Result.Success},
            new object[] {@"c:abcde/aa/bb/../..", true, false, false, Result.Success},
            new object[] {@"c:abcde/aa/bb/../../..", true, false, false, Result.Success},
            new object[] {@"c:abcde", true, false, true, Result.Success},
            new object[] {@"c:abcde/..", true, false, false, Result.Success},
            new object[] {@"c:abcde/", true, false, false, Result.Success},
            new object[] {@"///aa", true, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"//aa//bb", true, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"//aa//bb/..", true, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"//./bb", true, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"//../bb", true, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"//.../bb", true, false, false, Result.Success},
            new object[] {@"//aa$abc/bb", true, false, false, ResultFs.InvalidCharacter.Value},
            new object[] {@"//aa$/bb", true, false, false, ResultFs.InvalidCharacter.Value},
            new object[] {@"//aa:/bb", true, false, false, ResultFs.InvalidCharacter.Value},
            new object[] {@"//aa/bb$b/cc$", true, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"//aa/bb/cc$c", true, false, false, Result.Success},
            new object[] {@"//aa/bb/cc$c/..", true, false, false, Result.Success},
            new object[] {@"//aa/bb/cc$c/dd", true, false, false, Result.Success},
            new object[] {@"//aa/bb", true, false, false, Result.Success},
            new object[] {@"//aa/bb/cc//dd", true, false, false, Result.Success},
            new object[] {@"//aa/bb/cc//dd/..", true, false, false, Result.Success},
            new object[] {@"//aa/bb/cc//dd/../..", true, false, false, Result.Success},
            new object[] {@"//aa/bb/cc//dd/../../..", true, false, false, Result.Success},
            new object[] {@"//aa/bb/cc\/dd", true, false, false, Result.Success},
            new object[] {@"//aa/bb/cc//dd", true, false, false, Result.Success},
            new object[] {@"//aa/bb/cc/dd", true, false, false, Result.Success},
            new object[] {@"//aa/bb/cc/dd/..", true, false, false, Result.Success},
            new object[] {@"//aa/bb/cc/dd/../..", true, false, false, Result.Success},
            new object[] {@"//aa/bb/cc/dd/../../..", true, false, false, Result.Success},
            new object[] {@"//aa/bb/cc/\dd", true, false, false, Result.Success},
            new object[] {@"//aa/bb/cc/\dd/..", true, false, false, Result.Success},
            new object[] {@"//aa/bb/cc/\dd/../..", true, false, false, Result.Success},
            new object[] {@"//aa/bb/cc/\dd/../../..", true, false, false, Result.Success},
            new object[] {@"//aa/../", true, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"//aa//", true, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"//aa/bb..", true, false, false, Result.Success},
            new object[] {@"//aa/bb../..", true, false, false, Result.Success},
            new object[] {@"//aa/bb../", true, false, false, Result.Success},
            new object[] {@"//aa/bb..//..", true, false, false, Result.Success},
            new object[] {@"/\\aa/bb/cc/..", true, true, false, Result.Success},
            new object[] {@"/\\aa/bb/cc/../..", true, true, false, Result.Success},
            new object[] {@"/\\aa/bb/cc/../../..", true, true, false, Result.Success},
            new object[] {@"/\\aa/bb/cc/../../../..", true, true, false, Result.Success},
            new object[] {@"c:aa\bb/cc", true, false, true, Result.Success},
            new object[] {@"c:aa\bb/cc/..", true, false, false, Result.Success},
            new object[] {@"c:aa\bb/cc/../..", true, false, false, Result.Success},
            new object[] {@"c:aa\bb/cc/../../..", true, false, false, Result.Success},
            new object[] {@"c:\//\aa\bb", true, false, false, Result.Success},
            new object[] {@"c:\//\aa\bb/..", true, false, false, Result.Success},
            new object[] {@"mount://////a/bb/c", true, true, false, Result.Success},
            new object[] {@"mount://////a/bb/c/..", true, true, false, Result.Success},
            new object[] {@"mount://////a/bb/c/../..", true, true, false, Result.Success},
            new object[] {@"//", true, false, false, Result.Success},
            new object[] {@"///..", true, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"//a", true, false, false, Result.Success},
            new object[] {@"//a/..", true, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"//a", true, false, false, Result.Success},
            new object[] {@"//a/..", true, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"//a/", true, false, false, Result.Success},
            new object[] {@"//a//..", true, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"//a/b", true, false, false, Result.Success},
            new object[] {@"//a/b/..", true, false, false, Result.Success},
            new object[] {@"//a/b/", true, false, false, Result.Success},
            new object[] {@"//a/b//..", true, false, false, Result.Success},
            new object[] {@"//a/b/c", true, false, false, Result.Success},
            new object[] {@"//a/b/c/..", true, false, false, Result.Success},
            new object[] {@"//a/b/c/../..", true, false, false, Result.Success},
            new object[] {@"//a/b/c/", true, false, false, Result.Success},
            new object[] {@"//a/b/c//..", true, false, false, Result.Success},
            new object[] {@"//a/b/c//../..", true, false, false, Result.Success},
            new object[] {@"\\", true, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\/..", true, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a", true, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/..", true, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/", true, false, true, Result.Success},
            new object[] {@"\\a//..", true, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/b", true, false, true, Result.Success},
            new object[] {@"\\a/b/..", true, false, false, Result.Success},
            new object[] {@"\\a/b/", true, false, false, Result.Success},
            new object[] {@"\\a/b//..", true, false, false, Result.Success},
            new object[] {@"\\a/b/c", true, false, true, Result.Success},
            new object[] {@"\\a/b/c/..", true, false, false, Result.Success},
            new object[] {@"\\a/b/c/../..", true, false, false, Result.Success},
            new object[] {@"\\a/b/c/", true, false, false, Result.Success},
            new object[] {@"\\a/b/c//..", true, false, false, Result.Success},
            new object[] {@"\\a/b/c//../..", true, false, false, Result.Success},
            new object[] {@"\\", true, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\/..", true, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a", true, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a/..", true, false, false, ResultFs.InvalidPathFormat.Value},
            new object[] {@"\\a\", true, false, false, Result.Success},
            new object[] {@"\\a\/..", true, false, false, Result.Success},
            new object[] {@"\\a\b", true, false, false, Result.Success},
            new object[] {@"\\a\b/..", true, false, false, Result.Success},
            new object[] {@"\\a\b\", true, false, false, Result.Success},
            new object[] {@"\\a\b\/..", true, false, false, Result.Success},
            new object[] {@"\\a\b\c", true, false, false, Result.Success},
            new object[] {@"\\a\b\c/..", true, false, false, Result.Success},
            new object[] {@"\\a\b\c/../..", true, false, false, Result.Success},
            new object[] {@"\\a\b\c\", true, false, false, Result.Success},
            new object[] {@"\\a\b\c\/..", true, false, false, Result.Success},
            new object[] {@"\\a\b\c\/../..", true, false, false, Result.Success}
        };

        public static object[][] SubpathTestItems =
        {
            new object[] {@"//a/b", @"/a", false},
            new object[] {@"/a", @"//a/b", false},
            new object[] {@"//a/b", @"\\a", false},
            new object[] {@"//a/b", @"//a", true},
            new object[] {@"/", @"/a", true},
            new object[] {@"/a", @"/", true},
            new object[] {@"/", @"/", false},
            new object[] {@"", @"", false},
            new object[] {@"/", @"", true},
            new object[] {@"/", @"mount:/a", false},
            new object[] {@"mount:/", @"mount:/", false},
            new object[] {@"mount:/a/b", @"mount:/a/b", false},
            new object[] {@"mount:/a/b", @"mount:/a/b/c", true},
            new object[] {@"/a/b", @"/a/b/c", true},
            new object[] {@"/a/b/c", @"/a/b", true},
            new object[] {@"/a/b", @"/a/b", false},
            new object[] {@"/a/b", @"/a/b\c", false}
        };
    }
}
