text:
namespace ZetaLongPaths;

using Native;
using static String;

public static class ZlpPathHelper
{
    [PublicAPI]
    public static string GetPathRoot(string path)
    {
        if (IsNullOrEmpty(path))
        {
            return path;
        }
        else
        {
            path = ZlpIOHelper.ForceRemoveLongPathPrefix(path);

            return GetDriveOrShare(path);
        }
    }

    public static string ChangeExtension(string path, string extension)
    {
        if (path != null)
        {
            var text = path;
            var num = path.Length;

            while (--num >= 0)
            {
                var c = path[num];
                if (c == '.')
                {
                    text = path.Substring(0, num);
                    break;
                }

                if (c == Path.DirectorySeparatorChar || c == Path.AltDirectorySeparatorChar ||
                    c == Path.VolumeSeparatorChar)
                {
                    break;
                }
            }

            if (extension != null && path.Length != 0)
            {
                if (extension.Length == 0 || extension[0] != '.')
                {
                    text += ".";
                }

                text += extension;
            }

            return text;
        }

        return null;
    }

    public static string ChangeFileNameWithoutExtension(string path, string fileNameWithoutExtension)
    {
        var dir = GetDirectoryPathNameFromFilePath(path);
        var ext = GetExtension(path);

        return Combine(dir, fileNameWithoutExtension + ext);
    }

    public static string ChangeFileName(string path, string fileName)
    {
        var dir = GetDirectoryPathNameFromFilePath(path);
        return Combine(dir, fileName);
    }

    public static string GetFileNameFromFilePath(string filePath)
    {
        if (filePath == null) return null;

        var ls = filePath.LastIndexOfAny(new[]
            { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar, Path.VolumeSeparatorChar });
        return ls < 0 ? filePath : filePath.Substring(ls + 1);
    }

    public static string GetFileNameWithoutExtension(string filePath)
    {
        if (filePath == null) return null;

        var fn = GetFileNameFromFilePath(filePath);
        var ls = fn.LastIndexOf('.');

        return ls < 0 ? fn : fn.Substring(0, ls);
    }

    public static string GetDirectoryNameOnlyFromFilePath(string filePath)
    {
        // https://referencesource.microsoft.com/#mscorlib/system/io/directoryinfo.cs,e3b20cb1c28ea93f,references

        if (filePath == null) return null;

        string dirName;
        if (filePath.Length > 3)
        {
            var s = filePath;
            if (filePath.EndsWith(Path.DirectorySeparatorChar.ToString()) ||
                filePath.EndsWith(Path.AltDirectorySeparatorChar.ToString()))
            {
                s = filePath.Substring(0, filePath.Length - 1);
            }

            dirName = Path.GetFileName(s);
        }
        else
        {
            dirName = filePath; // For rooted paths, like "c:\"
        }

        return dirName;

        //var ls = filePath.LastIndexOfAny(new[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar/*, Path.VolumeSeparatorChar*/ });

        //return ls < 0 ? filePath : filePath.Substring(ls + 1);
    }

    /// <summary>
    /// Returns the full path.
    /// </summary>
    public static string GetDirectoryPathNameFromFilePath(string filePath)
    {
        if (filePath == null) return null;
        //filePath = filePath.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);

        var ls = filePath.LastIndexOfAny(new[]
            { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar /*, Path.VolumeSeparatorChar*/ });

        if (ls < 0)
        {
            return Empty;
        }
        else
        {
            var result = ConvertForwardSlashsToBackSlashs(filePath.Substring(0, ls));

            if (result.EndsWith(@":"))
            {
                return result + @"\";
            }
            else
            {
                return result;
            }
        }
    }

    /*
            private static void CheckInvalidPathChars(string path)
            {
                foreach (var t in path)
                {
                    var num = (int)t;
                    if (num == 34 || num == 60 || num == 62 || num == 124 || num < 32)
                    {
                        throw new ArgumentException(Resources.InvalidPathsCharacters);
                    }
                }
            }
    */

    /*
            private static bool IsDirectorySeparator(char c)
            {
                return c == Path.DirectorySeparatorChar || c == Path.AltDirectorySeparatorChar;
            }
    */

    /*
            internal static int GetRootLength(string path)
            {
                CheckInvalidPathChars(path);
                var i = 0;
                var length = path.Length;
                if (length >= 1 && IsDirectorySeparator(path[0]))
                {
                    i = 1;
                    if (length >= 2 && IsDirectorySeparator(path[1]))
                    {
                        i = 2;
                        var num = 2;
                        while (i < length)
                        {
                            if ((path[i] == Path.DirectorySeparatorChar || path[i] == Path.AltDirectorySeparatorChar) && --num <= 0)
                            {
                                break;
                            }
                            i++;
                        }
                    }
                }
                else
                {
                    if (length >= 2 && path[1] == Path.VolumeSeparatorChar)
                    {
                        i = 2;
                        if (length >= 3 && IsDirectorySeparator(path[2]))
                        {
                            i++;
                        }
                    }
                }
                return i;
            }
    */

    /// <summary>
    /// Makes 'path' an absolute path, based on 'basePath'.
    /// If the given path is already an absolute path, the path
    /// is returned unmodified.
    /// </summary>
    /// <param name="pathToMakeAbsolute">The path to make absolute.</param>
    /// <param name="basePathToWhichToMakeAbsoluteTo">The base path to use when making an
    /// absolute path.</param>
    /// <returns>Returns the absolute path.</returns>
    public static string GetAbsolutePath(
        string pathToMakeAbsolute,
        string basePathToWhichToMakeAbsoluteTo)
    {
        return IsAbsolutePath(pathToMakeAbsolute)
            ? pathToMakeAbsolute
            : GetFullPath(
                Combine(
                    basePathToWhichToMakeAbsoluteTo,
                    pathToMakeAbsolute));
    }

    /// <summary>
    /// Makes a path relative to another.
    /// (i.e. what to type in a "cd" command to get from
    /// the PATH1 folder to PATH2). works like e.g. developer studio,
    /// when you add a file to a project: there, only the relative
    /// path of the file to the project is stored, too.
    /// e.g.:
    /// path1  = "c:\folder1\folder2\folder4\"
    /// path2  = "c:\folder1\folder2\folder3\file1.txt"
    /// result = "..\folder3\file1.txt"
    /// </summary>
    /// <param name="pathToWhichToMakeRelativeTo">The path to which to make relative to.</param>
    /// <param name="pathToMakeRelative">The path to make relative.</param>
    /// <returns>
    /// Returns the relative path, IF POSSIBLE.
    /// If not possible (i.e. no same parts in PATH2 and the PATH1),
    /// returns the complete PATH2.
    /// </returns>
    public static string GetRelativePath(
        string pathToWhichToMakeRelativeTo,
        string pathToMakeRelative)
    {
        return internalGetRelativePath(pathToWhichToMakeRelativeTo, pathToMakeRelative, out _);
    }

    private static string internalGetRelativePath(
        string pathToWhichToMakeRelativeTo,
        string pathToMakeRelative,
        out string sameStart)
    {
        if (IsNullOrEmpty(pathToWhichToMakeRelativeTo) ||
            IsNullOrEmpty(pathToMakeRelative))
        {
            sameStart = null;
            return pathToMakeRelative;
        }
        else
        {
            var o = pathToWhichToMakeRelativeTo.ToLowerInvariant().Replace('/', '\\').TrimEnd('\\');
            var t = pathToMakeRelative.ToLowerInvariant().Replace('/', '\\');

            // --
            // Handle special cases for Driveletters and UNC shares.

            var td = GetDriveOrShare(t);
            var od = GetDriveOrShare(o);

            td = td.Trim();
            td = td.Trim('\\', '/');

            od = od.Trim();
            od = od.Trim('\\', '/');

            // Different drive or share, i.e. nothing common, skip.
            if (td != od)
            {
                sameStart = null;
                return pathToMakeRelative;
            }
            else
            {
                var ol = o.Length;
                var tl = t.Length;

                // compare each one, until different.
                var pos = 0;
                while (pos < ol && pos < tl && o[pos] == t[pos])
                {
                    pos++;
                }

                if (pos < ol)
                {
                    pos--;
                }

                // after comparison, make normal (i.e. NOT lowercase) again.
                t = pathToMakeRelative;

                // --

                // noting in common.
                if (pos <= 0)
                {
                    sameStart = null;
                    return t;
                }
                else
                {
                    // If not matching at a slash-boundary, navigate back until slash.
                    if (!(pos == ol || o[pos] == '\\' || o[pos] == '/'))
                    {
                        while (pos > 0 && o[pos] != '\\' && o[pos] != '/')
                        {
                            pos--;
                        }
                    }

                    // noting in common.
                    if (pos <= 0)
                    {
                        sameStart = null;
                        return t;
                    }
                    else
                    {
                        // --
                        // grab and split the reminders.

                        var oRemaining = o.Substring(pos);
                        oRemaining = oRemaining.Trim('\\', '/');

                        // Count how many folders are following in 'path1'.
                        // Count by splitting.
                        var oRemainingParts = oRemaining.Split('\\');

                        var tRemaining = t.Substring(pos);
                        tRemaining = tRemaining.Trim('\\', '/');

                        // --

                        var result = new StringBuilder();

                        // Path from path1 to common root.
                        foreach (var oRemainingPart in oRemainingParts)
                        {
                            if (!IsNullOrEmpty(oRemainingPart))
                            {
                                result.Append(@"..\");
                            }
                        }

                        // And up to 'path2'.
                        result.Append(tRemaining);

                        // --

                        sameStart = pathToMakeRelative.Substring(0, pos);
                        return result.ToString();
                    }
                }
            }
        }
    }

    public static string GetFullPath(string path)
    {
        path = ZlpIOHelper.CheckAddLongPathPrefix(path);

        // --
        // Determine length.

        var sb = new StringBuilder();

        var realLength = PInvokeHelper.GetFullPathName(path, 0, sb, IntPtr.Zero);

        // --

        sb.Length = realLength;
        realLength = PInvokeHelper.GetFullPathName(path, sb.Length, sb, IntPtr.Zero);

        if (realLength <= 0)
        {
            var lastWin32Error = Marshal.GetLastWin32Error();
            throw new Win32Exception(
                lastWin32Error,
                $"Error {lastWin32Error} getting full path for '{path}': {ZlpIOHelper.CheckAddDotEnd(new Win32Exception(lastWin32Error).Message)}");
        }
        else
        {
            return sb.ToString();
        }
    }

    public static string GetShortPath(string path)
    {
        path = ZlpIOHelper.CheckAddLongPathPrefix(path);

        // --
        // Determine length.

        var sb = new StringBuilder();

        var realLength = PInvokeHelper.GetShortPathName(path, sb, 0);

        // --

        sb.Length = (int)realLength;
        realLength = PInvokeHelper.GetShortPathName(path, sb, (uint)sb.Length);

        if (realLength <= 0)
        {
            var lastWin32Error = Marshal.GetLastWin32Error();
            throw new Win32Exception(
                lastWin32Error,
                $"Error {lastWin32Error} getting short path for '{path}': {ZlpIOHelper.CheckAddDotEnd(new Win32Exception(lastWin32Error).Message)}");
        }
        else
        {
            return sb.ToString();
        }
    }

    public static string GetLongPath(string path)
    {
        path = ZlpIOHelper.CheckAddLongPathPrefix(path);

        // --
        // Determine length.

        var sb = new StringBuilder();

        var realLength = PInvokeHelper.GetLongPathName(path, sb, 0);

        // --

        sb.Length = (int)realLength;
        realLength = PInvokeHelper.GetLongPathName(path, sb, (uint)sb.Length);

        if (realLength <= 0)
        {
            var lastWin32Error = Marshal.GetLastWin32Error();
            throw new Win32Exception(
                lastWin32Error,
                $"Error {lastWin32Error} getting long path for '{path}': {ZlpIOHelper.CheckAddDotEnd(new Win32Exception(lastWin32Error).Message)}");
        }
        else
        {
            return sb.ToString();
        }
    }

    public static string GetExtension(string path)
    {
        if (IsNullOrEmpty(path))
        {
            return path;
        }
        else
        {
            var splitted = path.Split(
                Path.DirectorySeparatorChar,
                Path.AltDirectorySeparatorChar,
                Path.VolumeSeparatorChar);

            if (splitted.Length > 0)
            {
                var p = splitted[splitted.Length - 1];

                var pos = p.LastIndexOf('.');
                return pos < 0 ? Empty : p.Substring(pos);
            }
            else
            {
                return Empty;
            }
        }
    }

    [PublicAPI]
    public static ZlpDirectoryInfo CombineDirectory(
        string path1,
        string path2)
    {
        return new(Combine(path1, path2));
    }

    [PublicAPI]
    public static ZlpFileInfo CombineFile(
        string path1,
        string path2)
    {
        return new(Combine(path1, path2));
    }

    /// <summary>
    /// <para>For most of the passed path1 and path 2, this method behaves similar to System.IO.Path.Combine.</para>
    /// <para>For some path2 however, this method behaves different: If path2 is a rooted path (i.e. a path starting with one backslash)
    /// System.IO.Path.Combine simply returns path2 whereas this method still combines path 1 and path 2.</para>
    /// </summary>
    public static string Combine(
        string path1,
        string path2)
    {
        if (IsNullOrEmpty(path1))
        {
            return path2;
        }
        else if (IsNullOrEmpty(path2))
        {
            return path1;
        }
        else
        {
            // https://github.com/UweKeim/ZetaLongPaths/issues/39
            if (IsAbsolutePath(path1) && IsAbsolutePath(path2))
            {
                var result = internalGetRelativePath(path1, path2, out var sameStart);

                if (!IsNullOrEmpty(sameStart))
                {
                    path1 = sameStart;
                    path2 = result;
                }
            }

            path1 = path1.TrimEnd('\\', '/').Replace('/', '\\');
            path2 = path2.TrimStart('\\', '/').Replace('/', '\\');

            return path1 + @"\" + path2;
        }
    }

    [PublicAPI] public static char DirectorySeparatorChar => Path.DirectorySeparatorChar;

    [PublicAPI] public static char AltDirectorySeparatorChar => Path.AltDirectorySeparatorChar;

    public static string GetTempDirectoryPath()
    {
        // Simply redirect.
        return Path.GetTempPath();
    }

    public static string GetTempFilePath()
    {
        // Simply redirect.
        return Path.GetTempFileName();
    }

    public static string GetTempFilePath(string extension)
    {
        return IsNullOrEmpty(extension)
            ? GetTempFilePath()
            // https://stackoverflow.com/a/581574/107625
            : $@"{Path.GetTempPath()}{Guid.NewGuid()}.{extension.TrimStart('.')}";
    }

    [PublicAPI]
    public static ZlpDirectoryInfo CombineDirectory(
        string path1,
        string path2,
        string path3,
        params string[] paths)
    {
        return new(Combine(path1, path2, path3, paths));
    }

    [PublicAPI]
    public static ZlpFileInfo CombineFile(
        string path1,
        string path2,
        string path3,
        params string[] paths)
    {
        return new(Combine(path1, path2, path3, paths));
    }

    [PublicAPI]
    public static string Combine(
        string path1,
        string path2,
        string path3,
        params string[] paths)
    {
        var resultPath = Combine(path1, path2);
        resultPath = Combine(resultPath, path3);

        if (paths != null)
        {
            resultPath = paths.Aggregate(resultPath, Combine);
        }

        return resultPath;
    }

    [PublicAPI]
    public static string ConvertBackSlashsToForwardSlashs(
        string text)
    {
        return IsNullOrEmpty(text) ? text : text.Replace('\\', '/');
    }

    [PublicAPI]
    public static string ConvertForwardSlashsToBackSlashs(
        string text)
    {
        return IsNullOrEmpty(text) ? text : text.Replace('/', '\\');
    }

    public static string GetDrive(
        string path)
    {
        if (IsNullOrEmpty(path))
        {
            return path;
        }
        else
        {
            path = ConvertForwardSlashsToBackSlashs(path);

            var colonPos = path.IndexOf(':');
            var slashPos = path.IndexOf('\\');

            if (colonPos <= 0)
            {
                return Empty;
            }
            else
            {
                if (slashPos < 0 || slashPos > colonPos)
                {
                    return path.Substring(0, colonPos + 1);
                }
                else
                {
                    return Empty;
                }
            }
        }
    }

    /// <summary>
    /// Retrieves the share in a given string.
    /// </summary>
    /// <returns>
    /// Returns the share or an empty string if not found.
    /// </returns>
    /// <remarks>
    /// Example: "\\Server\C\Team\Text\Test.Txt" would return "\\Server\C".
    /// -
    /// Please note_: Searches until the last backslash (including).
    /// If none is present, the share will not be detected. The schema of
    /// a share looks like: "\\Server\Share\Dir1\Dir2\Dir3". The backslash
    /// after "Share" MUST be present to be detected successfully as a share.
    /// </remarks>
    public static string GetShare(
        string path)
    {
        if (IsNullOrEmpty(path))
        {
            return path;
        }
        else
        {
            var str = path;

            // Nach Doppel-Slash suchen.
            // Kann z.B. "\\server\share\" sein,
            // aber auch "http:\\www.xyz.com\".
            const string dblslsh = @"\\";
            var n = str.IndexOf(dblslsh, StringComparison.Ordinal);
            if (n < 0)
            {
                return Empty;
            }
            else
            {
                // Übernehme links von Doppel-Slash alles in Rückgabe
                // (inkl. Doppel-Slash selbst).
                var ret = str.Substring(0, n + dblslsh.Length);
                str = str.Remove(0, n + dblslsh.Length);

                // Jetzt nach Slash nach Server-Name suchen.
                // Dieser Slash darf nicht unmittelbar nach den 2 Anfangsslash stehen.
                n = str.IndexOf('\\');
                if (n <= 0)
                {
                    return Empty;
                }
                else
                {
                    // Wiederum übernehmen in Rückgabestring.
                    ret += str.Substring(0, n + 1);
                    str = str.Remove(0, n + 1);

                    // Jetzt nach Slash nach Share-Name suchen.
                    // Dieser Slash darf ebenfalls nicht unmittelbar
                    // nach dem jetzigen Slash stehen.
                    n = str.IndexOf('\\');
                    switch (n)
                    {
                        case < 0:
                            n = str.Length;
                            break;
                        case 0:
                            return Empty;
                    }

                    // Wiederum übernehmen in Rückgabestring,
                    // aber ohne letzten Slash.
                    ret += str.Substring(0, n);

                    // The last item must not be a slash.
                    return ret[ret.Length - 1] == '\\' ? Empty : ret;
                }
            }
        }
    }

    public static string GetDriveOrShare(
        string path)
    {
        if (IsNullOrEmpty(path))
        {
            return path;
        }
        else
        {
            if (!IsNullOrEmpty(GetDrive(path)))
            {
                return GetDrive(path);
            }
            else if (!IsNullOrEmpty(GetShare(path)))
            {
                return GetShare(path);
            }
            else
            {
                return Empty;
            }
        }
    }

    /// <summary>
    /// Gets the drive or share and directory.
    /// </summary>
    [PublicAPI]
    public static string GetDriveOrShareAndDirectory(
        string path)
    {
        return IsNullOrEmpty(path)
            ? path
            : GetDirectoryPathNameFromFilePath(path);
    }

    /// <summary>
    /// Retrieves the path part in a given string (without the drive or share).
    /// </summary>
    /// <remarks>
    /// Example: "C:\Team\Text\Test.Txt" would return "\Test\Text\".
    /// -
    /// Please note_: Searches until the last backslash (including).
    /// If not present, the path is not treated as a directory.
    /// (E.g.. "C:\Test\MyDir" would return "\Test" only as the directory).
    /// </remarks>
    public static string GetDirectory(
        string path)
    {
        if (IsNullOrEmpty(path))
        {
            return path;
        }
        else
        {
            var driveOrShare = GetDriveOrShare(path);

            var dir = GetDirectoryPathNameFromFilePath(path);

            // ReSharper disable InvocationIsSkipped
            Debug.Assert(
                IsNullOrEmpty(driveOrShare) ||
                dir.StartsWith(driveOrShare),
                $@"Variable 'dir' ('{dir}') must start with drive or share '{driveOrShare}'.");
            // ReSharper restore InvocationIsSkipped

            if (!IsNullOrEmpty(driveOrShare) &&
                dir.StartsWith(driveOrShare))
            {
                return dir.Substring(driveOrShare.Length);
            }
            else
            {
                return dir;
            }
        }
    }

    /// <summary>
    /// Retrieves the file name without the extension in a given string.
    /// </summary>
    /// <remarks>
    /// Examples:
    /// "C:\Team\Text\Test.Txt" would return "Test".
    /// "C:\Team\Text\Test" would also return "Test".
    /// </remarks>
    public static string GetNameWithoutExtension(
        string path)
    {
        return IsNullOrEmpty(path)
            ? path
            : GetFileNameWithoutExtension(path);
    }

    /// <summary>
    /// Retrieves the file name with the extension in a given string.
    /// </summary>
    /// <remarks>
    /// Examples:
    /// "C:\Team\Text\Test.Txt" would return "Test.Txt".
    /// "C:\Team\Text\Test" would return "Test".
    /// </remarks>
    [PublicAPI]
    public static string GetNameWithExtension(
        ZlpFileInfo path)
    {
        return GetNameWithExtension(path.FullName);
    }

    /// <summary>
    /// Retrieves the file name with the extension in a given string.
    /// </summary>
    /// <remarks>
    /// Examples:
    /// "C:\Team\Text\Test.Txt" would return "Test.Txt".
    /// "C:\Team\Text\Test" would return "Test".
    /// </remarks>
    public static string GetNameWithExtension(
        string path)
    {
        return IsNullOrEmpty(path) ? path : GetFileNameFromFilePath(path);
    }

    [PublicAPI]
    public static ZlpSplittedPath SplitPath(
        string path)
    {
        return new ZlpFileOrDirectoryInfo(path).ZlpSplittedPath;
    }

    [PublicAPI]
    public static ZlpSplittedPath SplitPath(
        ZlpFileInfo path)
    {
        return new ZlpFileOrDirectoryInfo(path).ZlpSplittedPath;
    }

    [PublicAPI]
    public static ZlpSplittedPath SplitPath(
        ZlpDirectoryInfo path)
    {
        return new ZlpFileOrDirectoryInfo(path).ZlpSplittedPath;
    }

    [PublicAPI]
    public static ZlpSplittedPath SplitPath(
        ZlpFileOrDirectoryInfo path)
    {
        return path.ZlpSplittedPath;
    }

    [PublicAPI]
    public static bool IsDriveLetterPath(
        string filePath)
    {
        if (IsNullOrEmpty(filePath))
        {
            return false;
        }
        else
        {
            return filePath.IndexOf(':') == 1;
        }
    }

    [PublicAPI]
    public static bool IsUncPath(
        string filePath)
    {
        if (IsNullOrEmpty(filePath))
        {
            return false;
        }
        else
        {
            var s = ConvertForwardSlashsToBackSlashs(filePath);

            if (s.StartsWith(@"\\"))
            {
                if (s.StartsWith(@"\\?\UNC\"))
                {
                    return !IsNullOrEmpty(GetShare(filePath));
                }
                else if (s.StartsWith(@"\\?\"))
                {
                    return false;
                }
                else
                {
                    return !IsNullOrEmpty(GetShare(filePath));
                }
            }
            else
            {
                return false;
            }
        }
    }

    [PublicAPI]
    public static string SetBackSlashEnd(
        string path,
        bool setSlash)
    {
        return setSlashEnd(path, setSlash, '\\');
    }

    [PublicAPI]
    public static string SetForwardSlashEnd(
        string path,
        bool setSlash)
    {
        return setSlashEnd(path, setSlash, '/');
    }

    [PublicAPI]
    public static string SetBackSlashBegin(
        string path,
        bool setSlash)
    {
        return setSlashBegin(path, setSlash, '\\');
    }

    [PublicAPI]
    public static string SetForwardSlashBegin(
        string path,
        bool setSlash)
    {
        return setSlashBegin(path, setSlash, '/');
    }

    [PublicAPI]
    public static string GetParentPath(
        string text)
    {
        return IsNullOrEmpty(text)
            ? text
            : GetFullPath(Combine(text, @".."));
    }

    /// <summary>
    /// Check whether a given path contains an absolute or relative path.
    /// No disk-access is performed, only the syntax of the given string
    /// is checked.
    /// </summary>
    [PublicAPI]
    public static bool IsAbsolutePath(
        string path)
    {
        path = path.Replace('/', '\\');
        path = ZlpIOHelper.ForceRemoveLongPathPrefix(path);

        if (path.Length < 2)
        {
            return false;
        }
        else if (path.Substring(0, 2) == @"\\")
        {
            // UNC.
            return IsUncPath(path);
        }
        else if (path.Substring(1, 1) == @":")
        {
            // "C:"
            return IsDriveLetterPath(path);
        }
        else
        {
            return false;
        }
    }

    /// <summary>
    /// A "less intelligent" Combine (in contrast to to Path.Combine).
    /// For paths with forward slash.
    /// </summary>
    [PublicAPI]
    public static string CombineVirtual(
        string path1,
        string path2)
    {
        if (IsNullOrEmpty(path1))
        {
            return path2;
        }
        else if (IsNullOrEmpty(path2))
        {
            return path1;
        }
        else
        {
            // Avoid removing too much "/", so that "file://" still
            // stays "file://" and does not become "file:/".
            // (The same applies for other protocols.

            path1 = path1.Replace('\\', '/');
            if (path1[path1.Length - 1] != '/')
            {
                path1 += @"/";
            }

            path2 = path2.Replace('\\', '/');

            // Do allow "file://" + "/C:/..." to really form "file:///C:/...",
            // with three slashes.
            if (path2.Length >= 3)
            {
                if (path2[0] == '/' && path2[2] == ':' && char.IsLetter(path2[1]))
                {
                    // Is OK to have a leading slash.
                }
                else
                {
                    path2 = path2.TrimStart('/', '\\');
                }
            }
            else
            {
                path2 = path2.TrimStart('/', '\\');
            }

            return path1 + path2;
        }
    }

    /// <summary>
    /// A "less intelligent" Combine (in contrast to to Path.Combine).
    /// For paths with forward slash.
    /// </summary>
    [PublicAPI]
    public static string CombineVirtual(
        string path1,
        string path2,
        string path3,
        params string[] paths)
    {
        var resultPath = CombineVirtual(path1, path2);
        resultPath = CombineVirtual(resultPath, path3);

        if (paths != null)
        {
            resultPath = paths.Aggregate(resultPath, CombineVirtual);
        }

        return resultPath;
    }

    private static string setSlashBegin(
        string path,
        bool setSlash,
        char directorySeparatorChar)
    {
        if (setSlash)
        {
            if (IsNullOrEmpty(path))
            {
                return directorySeparatorChar.ToString();
            }
            else
            {
                if (path[0] == directorySeparatorChar)
                {
                    return path;
                }
                else
                {
                    return directorySeparatorChar + path;
                }
            }
        }
        else
        {
            if (IsNullOrEmpty(path))
            {
                return path;
            }
            else
            {
                return path[0] == directorySeparatorChar ? path.Substring(1) : path;
            }
        }
    }

    private static string setSlashEnd(
        string path,
        bool setSlash,
        char directorySeparatorChar)
    {
        if (setSlash)
        {
            if (IsNullOrEmpty(path))
            {
                return directorySeparatorChar.ToString();
            }
            else
            {
                if (path[path.Length - 1] == directorySeparatorChar)
                {
                    return path;
                }
                else
                {
                    return path + directorySeparatorChar;
                }
            }
        }
        else
        {
            if (IsNullOrEmpty(path))
            {
                return path;
            }
            else
            {
                return path[path.Length - 1] == directorySeparatorChar ? path.Substring(0, path.Length - 1) : path;
            }
        }
    }

    public static bool AreSameFolders(string folder1, string folder2)
    {
        return !IsNullOrEmpty(folder1) && !IsNullOrEmpty(folder2) &&
               folder1.TrimEnd('\\').ToLowerInvariant().Equals(folder2.TrimEnd('\\').ToLowerInvariant());
    }
}


text:
"""
Helper functions for incomplete matrices represented using dictionaries.
"""

from collections import defaultdict

import numpy as np
from scipy.sparse import dok_matrix

def dense_nan_matrix(shape, dtype):
    return np.ones(shape, dtype=dtype) * np.nan

def collect_nested_keys(nested_dict):
    outer_key_list = list(sorted(nested_dict.keys()))
    inner_key_set = set([])
    for k in outer_key_list:
        inner_dict = nested_dict[k]
        inner_key_set = inner_key_set.union(inner_dict.keys())
    inner_key_list = list(sorted(inner_key_set))
    return outer_key_list, inner_key_list

def nested_key_indices(nested_dict):
    """
    Give an ordering to the outer and inner keys used in a dictionary that
    maps to dictionaries.
    """
    outer_keys, inner_keys = collect_nested_keys(nested_dict)
    outer_key_indices = {k: i for (i, k) in enumerate(outer_keys)}
    inner_key_indices = {k: i for (i, k) in enumerate(inner_keys)}
    return outer_key_indices, inner_key_indices

def flattened_nested_key_indices(nested_dict):
    """
    Combine the outer and inner keys of nested dictionaries into a single
    ordering.
    """
    outer_keys, inner_keys = collect_nested_keys(nested_dict)
    combined_keys = list(sorted(set(outer_keys + inner_keys)))
    return {k: i for (i, k) in enumerate(combined_keys)}

def index_dict_to_sorted_list(key_indices):
    sorted_list = [None] * len(key_indices)
    for (key, index) in key_indices.items():
        sorted_list[index] = key
    return sorted_list

def array_from_nested_dictionary(
        nested_dict,
        array_fn,
        dtype="float32",
        square_result=False):
    """
    Parameters
    ----------
    nested_dict : dict
        Dictionary which contains dictionaries

    array_fn : function
        Takes shape and dtype as arguments, returns empty array.

    dtype : dtype
        NumPy dtype of result array

    square_result : bool
        Combine keys from outer and inner dictionaries.

    Returns array and sorted lists of the outer and inner keys.
    """
    if square_result:
        outer_key_indices = inner_key_indices = flattened_nested_key_indices(
            nested_dict)
    else:
        outer_key_indices, inner_key_indices = nested_key_indices(
            nested_dict)

    n_rows = len(outer_key_indices)
    n_cols = len(inner_key_indices)
    shape = (n_rows, n_cols)
    result = array_fn(shape, dtype)
    for outer_key, sub_dictionary in nested_dict.items():
        i = outer_key_indices[outer_key]
        for inner_key, value in sub_dictionary.items():
            j = inner_key_indices[inner_key]
            result[i, j] = value
    outer_key_list = index_dict_to_sorted_list(outer_key_indices)
    inner_key_list = index_dict_to_sorted_list(inner_key_indices)
    return result, outer_key_list, inner_key_list

def sparse_dok_matrix_from_nested_dictionary(
        nested_dict,
        dtype="float32",
        square_result=False):
    return array_from_nested_dictionary(
        nested_dict,
        array_fn=dok_matrix,
        dtype=dtype,
        square_result=square_result)

def dense_matrix_from_nested_dictionary(
        nested_dict,
        dtype="float32",
        square_result=False):
    return array_from_nested_dictionary(
        nested_dict,
        array_fn=dense_nan_matrix,
        dtype=dtype,
        square_result=square_result)

def matrix_to_pair_dictionary(
        X, row_keys=None, column_keys=None, filter_fn=None):
    """
    X : numpy.ndarray

    row_keys : dict
        Dictionary mapping indices to row names. If omitted then maps each
        number to its string representation, such as 1 -> "1".

    column_keys : dict
        If omitted and matrix is square, then use the same dictionary
        as the rows. Otherwise map each column index to its string form.

    filter_fn : function
        If given then only add elements for which this function returns True.
    """
    n_rows, n_cols = X.shape

    if row_keys is None:
        row_keys = {i: i for i in range(n_rows)}

    if column_keys is None:
        if n_rows == n_cols:
            column_keys = row_keys
        else:
            column_keys = {j: j for j in range(n_cols)}

    if len(row_keys) != n_rows:
        raise ValueError("Need %d row keys but got list of length %d" % (
            n_rows,
            len(row_keys)))

    if len(column_keys) != n_cols:
        raise ValueError("Need %d column keys but got list of length %d" % (
            n_cols,
            len(column_keys)))

    result_dict = {}
    for i, X_i in enumerate(X):
        row_key = row_keys[i]
        for j, X_ij in enumerate(X_i):
            if filter_fn and not filter_fn(X_ij):
                continue
            column_key = column_keys[j]
            key_pair = (row_key, column_key)
            result_dict[key_pair] = X_ij
    return result_dict

def curry_pair_dictionary(key_pair_dict, default_value=0.0):
    """
    Transform dictionary from pairs of keys to dict -> dict -> float
    """
    result = defaultdict(dict)
    for (a, b), value in key_pair_dict.items():
        result[a][b] = value
    return result

def uncurry_nested_dictionary(curried_dict):
    """
    Transform dictionary from (key_a -> key_b -> float) to
    (key_a, key_b) -> float
    """
    result = {}
    for a, a_dict in curried_dict.items():
        for b, value in a_dict.items():
            result[(a, b)] = value
    return result

def matrix_to_nested_dictionary(
        X,
        row_keys=None,
        column_keys=None,
        filter_fn=None):
    pair_dict = matrix_to_pair_dictionary(
        X,
        row_keys=row_keys,
        column_keys=column_keys,
        filter_fn=filter_fn)
    return curry_pair_dictionary(pair_dict)

def pair_dict_key_sets(pair_dict):
    row_keys = set([])
    column_keys = set([])
    for (row_key, column_key) in pair_dict.keys():
        row_keys.add(row_key)
        column_keys.add(column_key)
    return row_keys, column_keys

def array_from_pair_dictionary(
        pair_dict,
        array_fn,
        dtype="float32",
        square_result=False):
    """
    Convert a dictionary whose keys are pairs (k1, k2) into a sparse
    or incomplete array.

    Parameters
    ----------
    pair_dict : dict
        Dictionary from pairs of keys to values.

    array_fn : function
        Takes shape and dtype as arguments, returns empty array.

    dtype : dtype
        NumPy dtype of result array

    square_result : bool
        Combine keys from rows and columns

    Returns array and sorted lists of the row and column keys.
    """
    row_key_set, column_key_set = pair_dict_key_sets(pair_dict)

    if square_result:
        combined_key_set = row_key_set.union(column_key_set)
        row_key_list = column_key_list = list(sorted(combined_key_set))
        row_key_indices = column_key_indices = {
            k: i for (i, k) in enumerate(row_key_list)
        }
    else:
        row_key_list = list(sorted(row_key_set))
        column_key_list = list(sorted(column_key_set))
        row_key_indices = {k: i for (i, k) in enumerate(row_key_list)}
        column_key_indices = {k: i for (i, k) in enumerate(column_key_list)}

    n_rows = len(row_key_indices)
    n_cols = len(column_key_indices)
    shape = (n_rows, n_cols)
    result = array_fn(shape, dtype)
    for (row_key, column_key), value in pair_dict.items():
        i = row_key_indices[row_key]
        j = column_key_indices[column_key]
        result[i, j] = value
    return result, row_key_list, column_key_list

def sparse_dok_matrix_from_pair_dictionary(
        pair_dict,
        dtype="float32",
        square_result=False):
    return array_from_pair_dictionary(
        pair_dict,
        array_fn=dok_matrix,
        dtype=dtype,
        square_result=square_result)

def dense_matrix_from_pair_dictionary(
        pair_dict,
        dtype="float32",
        square_result=False):
    return array_from_pair_dictionary(
        pair_dict,
        array_fn=dense_nan_matrix,
        dtype=dtype,
        square_result=square_result)

def transpose_nested_dictionary(nested_dict):
    """
    Given a nested dictionary from k1 -> k2 > value
    transpose its outer and inner keys so it maps
    k2 -> k1 -> value.
    """
    result = defaultdict(dict)
    for k1, d in nested_dict.items():
        for k2, v in d.items():
            result[k2][k1] = v
    return result

def reverse_lookup_from_nested_dict(values_dict):
    """
    Create reverse-lookup dictionary mapping each row key to a list of triplets:
    [(column key, value), ...]

    Parameters
    ----------
    nested_values_dict : dict
        column_key -> row_key -> value

    weights_dict : dict
        column_key -> row_key -> sample weight

    Returns dictionary mapping row_key -> [(column key, value)]
    """
    reverse_lookup = defaultdict(list)
    for column_key, column_dict in values_dict.items():
        for row_key, value in column_dict.items():
            entry = (column_key, value)
            reverse_lookup[row_key].append(entry)
    return reverse_lookup

redpajama_set_name: RedPajamaGithub


text:
/**
 * @file emst_test.cpp
 *
 * Test file for EMST methods.
 */
#include <mlpack/core.hpp>
#include <mlpack/methods/emst/dtb.hpp>
#include <boost/test/unit_test.hpp>
#include "old_boost_test_definitions.hpp"

#include <mlpack/core/tree/cover_tree.hpp>

using namespace mlpack;
using namespace mlpack::emst;
using namespace mlpack::tree;
using namespace mlpack::bound;
using namespace mlpack::metric;

BOOST_AUTO_TEST_SUITE(EMSTTest);

/**
 * Simple emst test with small, synthetic dataset.  This is an
 * exhaustive test, which checks that each method for performing the calculation
 * (dual-tree, naive) produces the correct results.  The dataset is in one
 * dimension for simplicity -- the correct functionality of distance functions
 * is not tested here.
 */
BOOST_AUTO_TEST_CASE(ExhaustiveSyntheticTest)
{
  // Set up our data.
  arma::mat data(1, 11);
  data[0] = 0.05; // Row addressing is unnecessary (they are all 0).
  data[1] = 0.37;
  data[2] = 0.15;
  data[3] = 1.25;
  data[4] = 5.05;
  data[5] = -0.22;
  data[6] = -2.00;
  data[7] = -1.30;
  data[8] = 0.45;
  data[9] = 0.91;
  data[10] = 1.00;

  arma::mat results;

  // Build the tree by hand to get a leaf size of 1.
  typedef KDTree<EuclideanDistance, DTBStat, arma::mat> TreeType;
  std::vector<size_t> oldFromNew;
  std::vector<size_t> newFromOld;
  TreeType tree(data, oldFromNew, newFromOld, 1);

  // Create the DTB object and run the calculation.
  DualTreeBoruvka<> dtb(&tree);
  dtb.ComputeMST(results);

  // Now the exhaustive check for correctness.
  if (newFromOld[1] < newFromOld[8])
  {
    BOOST_REQUIRE_EQUAL(results(0, 0), newFromOld[1]);
    BOOST_REQUIRE_EQUAL(results(1, 0), newFromOld[8]);
  }
  else
  {
    BOOST_REQUIRE_EQUAL(results(1, 0), newFromOld[1]);
    BOOST_REQUIRE_EQUAL(results(0, 0), newFromOld[8]);
  }
  BOOST_REQUIRE_CLOSE(results(2, 0), 0.08, 1e-5);

  if (newFromOld[9] < newFromOld[10])
  {
    BOOST_REQUIRE_EQUAL(results(0, 1), newFromOld[9]);
    BOOST_REQUIRE_EQUAL(results(1, 1), newFromOld[10]);
  }
  else
  {
    BOOST_REQUIRE_EQUAL(results(1, 1), newFromOld[9]);
    BOOST_REQUIRE_EQUAL(results(0, 1), newFromOld[10]);
  }
  BOOST_REQUIRE_CLOSE(results(2, 1), 0.09, 1e-5);

  if (newFromOld[0] < newFromOld[2])
  {
    BOOST_REQUIRE_EQUAL(results(0, 2), newFromOld[0]);
    BOOST_REQUIRE_EQUAL(results(1, 2), newFromOld[2]);
  }
  else
  {
    BOOST_REQUIRE_EQUAL(results(1, 2), newFromOld[0]);
    BOOST_REQUIRE_EQUAL(results(0, 2), newFromOld[2]);
  }
  BOOST_REQUIRE_CLOSE(results(2, 2), 0.1, 1e-5);

  if (newFromOld[1] < newFromOld[2])
  {
    BOOST_REQUIRE_EQUAL(results(0, 3), newFromOld[1]);
    BOOST_REQUIRE_EQUAL(results(1, 3), newFromOld[2]);
  }
  else
  {
    BOOST_REQUIRE_EQUAL(results(1, 3), newFromOld[1]);
    BOOST_REQUIRE_EQUAL(results(0, 3), newFromOld[2]);
  }
  BOOST_REQUIRE_CLOSE(results(2, 3), 0.22, 1e-5);

  if (newFromOld[3] < newFromOld[10])
  {
    BOOST_REQUIRE_EQUAL(results(0, 4), newFromOld[3]);
    BOOST_REQUIRE_EQUAL(results(1, 4), newFromOld[10]);
  }
  else
  {
    BOOST_REQUIRE_EQUAL(results(1, 4), newFromOld[3]);
    BOOST_REQUIRE_EQUAL(results(0, 4), newFromOld[10]);
  }
  BOOST_REQUIRE_CLOSE(results(2, 4), 0.25, 1e-5);

  if (newFromOld[0] < newFromOld[5])
  {
    BOOST_REQUIRE_EQUAL(results(0, 5), newFromOld[0]);
    BOOST_REQUIRE_EQUAL(results(1, 5), newFromOld[5]);
  }
  else
  {
    BOOST_REQUIRE_EQUAL(results(1, 5), newFromOld[0]);
    BOOST_REQUIRE_EQUAL(results(0, 5), newFromOld[5]);
  }
  BOOST_REQUIRE_CLOSE(results(2, 5), 0.27, 1e-5);

  if (newFromOld[8] < newFromOld[9])
  {
    BOOST_REQUIRE_EQUAL(results(0, 6), newFromOld[8]);
    BOOST_REQUIRE_EQUAL(results(1, 6), newFromOld[9]);
  }
  else
  {
    BOOST_REQUIRE_EQUAL(results(1, 6), newFromOld[8]);
    BOOST_REQUIRE_EQUAL(results(0, 6), newFromOld[9]);
  }
  BOOST_REQUIRE_CLOSE(results(2, 6), 0.46, 1e-5);

  if (newFromOld[6] < newFromOld[7])
  {
    BOOST_REQUIRE_EQUAL(results(0, 7), newFromOld[6]);
    BOOST_REQUIRE_EQUAL(results(1, 7), newFromOld[7]);
  }
  else
  {
    BOOST_REQUIRE_EQUAL(results(1, 7), newFromOld[6]);
    BOOST_REQUIRE_EQUAL(results(0, 7), newFromOld[7]);
  }
  BOOST_REQUIRE_CLOSE(results(2, 7), 0.7, 1e-5);

  if (newFromOld[5] < newFromOld[7])
  {
    BOOST_REQUIRE_EQUAL(results(0, 8), newFromOld[5]);
    BOOST_REQUIRE_EQUAL(results(1, 8), newFromOld[7]);
  }
  else
  {
    BOOST_REQUIRE_EQUAL(results(1, 8), newFromOld[5]);
    BOOST_REQUIRE_EQUAL(results(0, 8), newFromOld[7]);
  }
  BOOST_REQUIRE_CLOSE(results(2, 8), 1.08, 1e-5);

  if (newFromOld[3] < newFromOld[4])
  {
    BOOST_REQUIRE_EQUAL(results(0, 9), newFromOld[3]);
    BOOST_REQUIRE_EQUAL(results(1, 9), newFromOld[4]);
  }
  else
  {
    BOOST_REQUIRE_EQUAL(results(1, 9), newFromOld[3]);
    BOOST_REQUIRE_EQUAL(results(0, 9), newFromOld[4]);
  }
  BOOST_REQUIRE_CLOSE(results(2, 9), 3.8, 1e-5);
}

/**
 * Test the dual tree method against the naive computation.
 *
 * Errors are produced if the results are not identical.
 */
BOOST_AUTO_TEST_CASE(DualTreeVsNaive)
{
  arma::mat inputData;

  // Hard-coded filename: bad!
  // Code duplication: also bad!
  if (!data::Load("test_data_3_1000.csv", inputData))
    BOOST_FAIL("Cannot load test dataset test_data_3_1000.csv!");

  // Set up matrices to work with.
  arma::mat dualData = inputData;
  arma::mat naiveData = inputData;

  // Reset parameters from last test.
  DualTreeBoruvka<> dtb(dualData);

  arma::mat dualResults;
  dtb.ComputeMST(dualResults);

  // Set naive mode.
  DualTreeBoruvka<> dtbNaive(naiveData, true);

  arma::mat naiveResults;
  dtbNaive.ComputeMST(naiveResults);

  BOOST_REQUIRE_EQUAL(dualResults.n_cols, naiveResults.n_cols);
  BOOST_REQUIRE_EQUAL(dualResults.n_rows, naiveResults.n_rows);

  for (size_t i = 0; i < dualResults.n_cols; i++)
  {
    BOOST_REQUIRE_EQUAL(dualResults(0, i), naiveResults(0, i));
    BOOST_REQUIRE_EQUAL(dualResults(1, i), naiveResults(1, i));
    BOOST_REQUIRE_CLOSE(dualResults(2, i), naiveResults(2, i), 1e-5);
  }
}

/**
 * Make sure the cover tree works fine.
 */
BOOST_AUTO_TEST_CASE(CoverTreeTest)
{
  arma::mat inputData;
  if (!data::Load("test_data_3_1000.csv", inputData))
    BOOST_FAIL("Cannot load test dataset test_data_3_1000.csv!");

  DualTreeBoruvka<> bst(inputData);
  DualTreeBoruvka<EuclideanDistance, arma::mat, StandardCoverTree>
      ct(inputData);

  arma::mat bstResults;
  arma::mat coverResults;

  // Run the algorithms.
  bst.ComputeMST(bstResults);
  ct.ComputeMST(coverResults);

  for (size_t i = 0; i < bstResults.n_cols; i++)
  {
    BOOST_REQUIRE_EQUAL(bstResults(0, i), coverResults(0, i));
    BOOST_REQUIRE_EQUAL(bstResults(1, i), coverResults(1, i));
    BOOST_REQUIRE_CLOSE(bstResults(2, i), coverResults(2, i), 1e-5);
  }

}

/**
 * Test BinarySpaceTree with Ball Bound.
 */
BOOST_AUTO_TEST_CASE(BallTreeTest)
{
  arma::mat inputData;
  if (!data::Load("test_data_3_1000.csv", inputData))
    BOOST_FAIL("Cannot load test dataset test_data_3_1000.csv!");

  // naive mode.
  DualTreeBoruvka<> bst(inputData, true);
  // Ball tree.
  DualTreeBoruvka<EuclideanDistance, arma::mat, BallTree> ballt(inputData);

  arma::mat bstResults;
  arma::mat ballResults;

  // Run the algorithms.
  bst.ComputeMST(bstResults);
  ballt.ComputeMST(ballResults);

  for (size_t i = 0; i < bstResults.n_cols; i++)
  {
    BOOST_REQUIRE_EQUAL(bstResults(0, i), ballResults(0, i));
    BOOST_REQUIRE_EQUAL(bstResults(1, i), ballResults(1, i));
    BOOST_REQUIRE_CLOSE(bstResults(2, i), ballResults(2, i), 1e-5);
  }

}

BOOST_AUTO_TEST_SUITE_END();


text:
#include <assert.h>
#include <string.h>
#include "binson_parser.h"

/*
{
  "": 68
}
*/
int main(void)
{
    uint8_t binson_bytes[6] = "\x40\x14\x00\x10\x44\x41";
    BINSON_PARSER_DEF(p);
    double dval; (void) dval;
    int64_t intval; (void) intval;
    bool boolval; (void) boolval;
    bbuf *rawval; (void) rawval;
    assert(binson_parser_init(&p, binson_bytes, sizeof(binson_bytes)));
    assert(binson_parser_verify(&p));
    assert(p.error_flags == BINSON_ID_OK);
    assert(binson_parser_go_into_object(&p));
    assert(p.error_flags == BINSON_ID_OK);
    assert(binson_parser_field_ensure_with_length(&p, "", 0, BINSON_TYPE_INTEGER));
    assert(p.error_flags == BINSON_ID_OK);
    intval = binson_parser_get_integer(&p);
    assert(p.error_flags == BINSON_ID_OK);
    assert(intval == 68);
    assert(!binson_parser_next(&p));
    assert(binson_parser_leave_object(&p));
    assert(p.error_flags == BINSON_ID_OK);
    return 0;
}


text:
<?php
/*
 * Generated by CRUDigniter v3.2
 * www.crudigniter.com
 */

class Knamespace_model extends CI_Model
{
    function __construct()
    {
        parent::__construct();
    }

    /*
     * Get knamespace by id
     */
    function get_knamespace($id)
    {
        return $this->db->get_where('namespaces',array('id'=>$id))->row_array();
    }

    /*
     * Get knamespace by name
     */
    function get_knamespace_by_name($name)
    {
        return $this->db->get_where('namespaces',array('name'=>$name))->row_array();
    }

    /*
     * Get all knamespaces count
     */
    function get_all_knamespaces_count()
    {
        $this->db->from('namespaces');
        return $this->db->count_all_results();
    }

    /*
     * Get all knamespaces
     */
    function get_all_knamespaces($params = array())
    {
	      $this->db->order_by('name', 'asc');
        if(isset($params) && !empty($params))
        {
            $this->db->limit($params['limit'], $params['offset']);
        }
        return $this->db->get('namespaces')->result_array();
    }

    /*
     * function to add new knamespace
     */
    function add_knamespace($params)
    {
        $this->db->insert('namespaces',$params);
        return $this->db->insert_id();
    }

    /*
     * function to update knamespace
     */
    function update_knamespace($id,$params)
    {
        $this->db->where('id',$id);
        return $this->db->update('namespaces',$params);
    }

    /*
     * function to delete knamespace
     */
    function delete_knamespace($id)
    {
        return $this->db->delete('namespaces',array('id'=>$id));
    }
}


text:
package com.ocdsoft.bacta.swg.precu.message.game.messagequeue;

/**
 * Created by crush on 8/13/2014.
 */
public class MessageQueueQuestTaskCounterMessage {
    //string questName
    //int taskId
    //UnicodeString sourceName
    //int counterValue
    //int counterMax
}


text:
<?php

namespace Theomessin\Vatauth\Traits;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Theomessin\Vatauth\Repository\SSO as Vatauth;

trait viaVatsim
{
    /**
     * Prepare an OAuth request to send to the VATSIM server
     *
     * @param \Theomessin\Vatauth\Repository\SSOVatauth $vatauth
     * @return mixed
     */
    public function fire(Vatauth $vatauth)
    {
        $callback = function($key, $secret, $url) {
            session(['vatauth' => compact('key', 'secret')]);
            return redirect($url);
        };

        return $vatauth->login(route('handle'), $callback);
    }

    /**
     * Handle a VATSIM SSO authentication request
     *
     * @param \Theomessin\Vatauth\Repository\SSOVatauth $vatauth
     * @param Request $request
     * @return mixed
     */
    public function handle(Vatauth $vatauth, Request $request)
    {
        $callback = function($e) use ($request) {
            $request->session()->forget('vatauth');
            config('vatauth.users.model')::sync($e);
            Auth::loginUsingId($e->id, true);
            return redirect()->intended($this->redirectTo);
        };

        return $vatauth->validate(session('vatauth.key'), session('vatauth.secret'), $request->input('oauth_verifier'), $callback);
    }
}


text:
void TwoTextureAccessFsParam::EnableTexture()
{
    cgGLEnableTextureParameter(decal);
}

void TwoTextureAccessFsParam::DisableTexture()
{
    cgGLDisableTextureParameter(decal);
}

void TwoTextureAccessFsParam::SetTexture(GLuint name)
{
    _SetTextureParam(decal, name);
}

void TwoTextureAccessFsParam::ExtractParams()
{
    _GetProgramParam(decal, "decal");
}

TwoTextureAccessFsParam::TwoTextureAccessFsParam(const CgShader& shader) :CgShaderParametersBase(shader)
{
}


text:
// Copyright 2014 The Oppia Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview Components used by both the editor and reader of the
 *  LogicProof interaction.
 */

var logicProofShared = (function() {
  // Used by parseLineString() to limit the number of possible parsings of a
  // line (or line template) considered.
  var MAX_NUM_PARSINGS_PERMITTED = 1000;
  // Used by assignTypesToExpressionArray() to limit the number of possible
  // typings of an expression considered.
  var MAX_NUM_TYPINGS_PERMITTED = 1000;

  // ERROR-HANDLING

  // UserErrors have codes that refer to entries in the errorDictionary (which
  // is either logicProofData.BASE_GENERAL_MESSAGES or
  // logicProofTeacher.TEACHER_ERROR_MESSAGES), from which a human-readable
  // message can be constructed.
  var UserError = function(code, parameters) {
    this.name = 'UserError';
    this.code = code;
    this.parameters = parameters || {};
  };

  // These errors already have messages which are user-readable.
  var PreRenderedUserError = function(messages, code) {
    this.name = 'PreRenderedUserError';
    this.messages = messages;
    this.code = code;
  };
  // TODO (Jacob) Make these errors prototype from Error()

  /** Converts a message template into a string to show to the user.
   * @param messageTemplate: a GeneralMessageTemplate object that determines how
   * to build the string describing an error.
   * @param parameterFormats: a dictionary of GeneralMessageParameters, which
   *        specify the format of the parameter in question (e.g. 'string').
   * @param parameters: a dictionary giving the values of the parameters for
   *        this particular instance of the message.
   * @param language: the relevant Language.
   * @result a user-readable string.
   */
  var renderGeneralMessage = function(
      messageTemplate, parameterFormats, parameters, language) {
    var message = '';
    for (var i = 0; i < messageTemplate.length; i++) {
      if (messageTemplate[i].isFixed) {
        message += messageTemplate[i].content;
      } else {
        var parameterFormat = parameterFormats[
          messageTemplate[i].content].format;
        var parameter = parameters[messageTemplate[i].content];
        switch (parameterFormat) {
          case 'string':
            message += parameter;
            break;
          case 'expression':
            message += displayExpression(parameter, language.operators);
            break;
          default:
            throw Error(
              'Unknown format ' + parameterFormat +
              ' sent to renderGeneralMessage().');
        }
      }
    }
    return message;
  };

  /**
   * @param {UserError} error - a UserError object
   * @param {object} errorDictionary - a dictionary keyed by error codes for
   *        each of which it provides a description of possible ways to display
   *        the error to the user, one of which will be chosen at random.
   * @param {Language} language - the relevant Language
   * @return {string} A string to show to the user describing what went wrong.
   */
  var renderError = function(error, errorDictionary, language) {
    if (error.name === 'UserError') {
      if (!errorDictionary.hasOwnProperty(error.code)) {
        throw new Error(
          'Unknown error code ' + error.code + ' sent to renderError().');
      }
      var messageTemplates = errorDictionary[error.code].templates;
      var messageTemplate = messageTemplates[
        Math.floor((Math.random() * messageTemplates.length))];
      return renderGeneralMessage(
        messageTemplate, errorDictionary[error.code].parameters,
        error.parameters, language);
    } else if (error.name === 'PreRenderedUserError') {
      return error.messages[
        Math.floor((Math.random() * error.messages.length))];
    } else {
      throw error;
    }
  };

  // DISPLAY

  /**
   * @param {Expression} expression - an Expression, which is to be displayed
   * @param {object} operators - provides the symbols keys of the operators so
   *        that we we know e.g. 'for_all' should be displayed using '@'.
   * @return {string} A string representing the expression that can be shown to
   *        the user.
   */
  var displayExpression = function(expression, operators) {
    return displayExpressionHelper(expression, operators, 0);
  };

  /**
   * Recursive helper for displayExpression().
   *
   * @param {Expression} expression - an Expression, which is to be displayed
   * @param {object} operators - provides the symbols keys of the operators so
   *        that we we know e.g. 'for_all' should be displayed using '@'.
   * @param {int} desirabilityOfBrackets - used internally to determine whether
   *        to surround the formula with brackets.
   * @return {string} A string representing the expression.
   */
  var displayExpressionHelper = function(
      expression, operators, desirabilityOfBrackets) {
    var desirabilityOfBracketsBelow = (
        expression.top_kind_name === 'binary_connective' ||
        expression.top_kind_name === 'binary_relation' ||
        expression.top_kind_name === 'binary_function'
      ) ? 2 : (
        expression.top_kind_name === 'unary_connective' ||
        expression.top_kind_name === 'quantifier'
      ) ? 1 : 0;
    var processedArguments = [];
    var processedDummies = [];
    for (var i = 0; i < expression.arguments.length; i++) {
      processedArguments.push(
        displayExpressionHelper(
          expression.arguments[i], operators, desirabilityOfBracketsBelow));
    }
    for (var i = 0; i < expression.dummies.length; i++) {
      processedDummies.push(
        displayExpressionHelper(
          expression.dummies[i], operators, desirabilityOfBracketsBelow));
    }

    var symbol = (!operators.hasOwnProperty(expression.top_operator_name)) ?
      expression.top_operator_name :
      (!operators[expression.top_operator_name].hasOwnProperty('symbols')) ?
        expression.top_operator_name :
        operators[expression.top_operator_name].symbols[0];

    if (expression.top_kind_name === 'binary_connective' ||
        expression.top_kind_name === 'binary_relation' ||
        expression.top_kind_name === 'binary_function') {
      return (
        desirabilityOfBrackets > 0 ?
        '(' + processedArguments.join(symbol) + ')' :
        processedArguments.join(symbol));
    } else if (expression.top_kind_name === 'unary_connective') {
      var output = symbol + processedArguments[0];
      return (desirabilityOfBrackets === 2) ? '(' + output + ')' : output;
    } else if (expression.top_kind_name === 'quantifier') {
      var output = symbol + processedDummies[0] + '.' + processedArguments[0];
      return (desirabilityOfBrackets === 2) ? '(' + output + ')' : output;
    } else if (expression.top_kind_name === 'bounded_quantifier') {
      var output = symbol + processedArguments[0] + '.' + processedArguments[1];
      return (desirabilityOfBrackets === 2) ? '(' + output + ')' : output;
    } else if (expression.top_kind_name === 'prefix_relation' ||
        expression.top_kind_name === 'prefix_function') {
      return symbol + '(' + processedArguments.join(',') + ')';
    } else if (expression.top_kind_name === 'ranged_function') {
      return (
        symbol + '{' + processedArguments[0] + ' | ' + processedArguments[1] +
        '}');
    } else if (expression.top_kind_name === 'atom' ||
      expression.top_kind_name === 'constant' ||
      expression.top_kind_name === 'variable') {
      return symbol;
    } else {
      throw Error(
        'Unknown kind ' + expression.top_kind_name +
        ' sent to displayExpression()');
    }
  };

  var displayExpressionArray = function(expressionArray, operators) {
    var processedArray = [];
    for (var i = 0; i < expressionArray.length; i++) {
      processedArray.push(
        displayExpressionHelper(expressionArray[i], operators));
    }
    return processedArray.join(', ');
  };

  // PARSING

  /**
   * This function checks whether the string contains any symbol that occurs
   * in a member of the symbols key for some operator (these will be
   * symbols such as ∀, =, <).
   * @param {string} string - contains the characters we check
   * @param {object} operators - a dictionary of Operator objects
   * @param {boolean} isTemplate - denotes that the string represents a line
   *        template (which may have substitutions) and not just a line.
   * @return {boolean} true or false
   */
  var containsLogicalCharacter = function(string, operators, isTemplate) {
    var GENERAL_LOGICAL_CHARACTERS = '(),';
    var TEMPLATE_LOGICAL_CHARACTERS = '[->]{|}';

    if (containsCharacterFromArray(string, GENERAL_LOGICAL_CHARACTERS)) {
      return true;
    }
    if (isTemplate &&
        containsCharacterFromArray(string, TEMPLATE_LOGICAL_CHARACTERS)) {
      return true;
    }

    for (var key in operators) {
      if (operators[key].hasOwnProperty('symbols')) {
        for (var i = 0; i < operators[key].symbols.length; i++) {
          // We check each character of a multi-character symbol in turn.
          for (var j = 0; j < operators[key].symbols[i].length; j++) {
            if (string.indexOf(operators[key].symbols[i][j]) !== -1) {
              return true;
            }
          }
        }
      }
    }
    return false;
  };

  /**
   * This function strips whitespace from within expressions, whilst using the
   * whitespace between expressions to split a line into an array of word /
   * expression strings.
   *  e.g. 'from p and q we have p ∧ q' will be converted to ['from', 'p',
   *   'and', 'q', 'we', 'have', 'p∧q'].
   * @param {string} inputString - the string from which whitespace is to be
   *        stripped.
   * @param {object} operators - a dictionary of the Operator objects usable in
   *        the line
   * @param {boolean} isTemplate - denotes that the string represents a line
   *        template (which may have substitutions) and not just a line.
   * @return {Array} A non-empty array of words and expressions (as strings).
   * @throws if the line is blank or contains an unknown character.
   */
  var preParseLineString = function(inputString, operators, isTemplate) {
    // The logical characters that may occur at the start and end of a formula
    // respectively. The unicode characters are 'for all' and 'exists'.
    var POSSIBLE_START_CHARS = '({\u2200\u2203~';
    var POSSIBLE_END_CHARS = ')}]';

    var POSSIBLE_NAME_CHARS = (
      'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 _');

    var _absorbsSpacesToTheLeft = function(character) {
      return containsLogicalCharacter(character, operators, isTemplate) &&
        !containsCharacter(POSSIBLE_START_CHARS, character);
    };
    var _absorbsSpacesToTheRight = function(character) {
      return (containsLogicalCharacter(character, operators, isTemplate) &&
        !containsCharacter(POSSIBLE_END_CHARS, character)) ||
        character === ' ';
    };
    var _isLegalCharacter = function(character) {
      return containsCharacter(POSSIBLE_NAME_CHARS, character) ||
        containsLogicalCharacter(character, operators, isTemplate);
    };

    var strippedString = '';
    for (var i = 0; i < inputString.length; i++) {
      if (!_isLegalCharacter(inputString[i])) {
        throw new UserError('illegal_symbol', {
          symbol: inputString[i]
        });
      }
      // We keep all non-spaces, and all spaces that are absorbed neither by
      // characters to their left nor their right.
      if (inputString[i] !== ' ' ||
          (i === 0 || !_absorbsSpacesToTheRight(
            strippedString[strippedString.length - 1])) &&
          (i === inputString.length - 1 || !_absorbsSpacesToTheLeft(
            inputString[i + 1]))) {
        strippedString += inputString[i];
      }
    }

    if (strippedString.replace(/ /g, '') === '') {
      throw new UserError('blank_line', {});
    }
    return strippedString.trim().split(' ');
  };

  /**
   * @param {string} inputString - written by the user - we will parse it.
   * @param {object} operators - the relevant operators, which are just needed
   *        for their symbols so we can identify whether the symbols the user
   *        is using are legitimate.
   * @param {object} vocabulary - a dictionary whose keys are phrases such as
   *        'have' whose entries are arrays of possible ways to write each
   *        phrase, for example ['have', 'we have']. We will attempt to match
   *        sections of the inputString to the ways of writing each phrase.
   * @param {boolean} isTemplate - if true, we parse the input as a
   *        LineTemplate; otherwise we parse it as a Line.
   * @return {*} A LineTemplate.reader_view if isTemplate === true, and a
   *         ProtoLine if isTemplate === false.
   * @throws If a section of the string cannot be identified as either a phrase
   *         or an expression then we throw an error that tries to best identify
   *         what the user intended and did wrong.
   */
  var parseLineString = function(
      inputString, operators, vocabulary, isTemplate) {
    var unparsedArray = preParseLineString(inputString, operators, isTemplate);

    // We compile all words occurring in the vocabulary, to help us identify
    // them in lines.
    var vocabularyWords = [];
    for (var key in vocabulary) {
      for (var i = 0; i < vocabulary[key].length; i++) {
        for (var j = 0; j < vocabulary[key][i].split(' ').length; j++) {
          if (vocabularyWords.indexOf(
                vocabulary[key][i].split(' ')[j]) === -1) {
            vocabularyWords.push(vocabulary[key][i].split(' ')[j]);
          }
        }
      }
    }

    // The lth entry in this array will contain all parsings of the first
    // l-many elements of the unparsedArray.
    var partiallyParsedArrays = [[[]]];
    for (var i = 1; i <= unparsedArray.length; i++) {
      partiallyParsedArrays.push([]);
    }

    for (var i = 0; i < unparsedArray.length; i++) {
      // We have parsed the first i-many entries in the given unparsedArray,
      // and will now attempt to parse the next one.

      // This will only occur in pathological cases
      if (partiallyParsedArrays[i].length > MAX_NUM_PARSINGS_PERMITTED) {
        throw new UserError('too_many_parsings', {});
      }

      for (var j = i + 1; j <= unparsedArray.length; j++) {
        for (var key in vocabulary) {
          for (var k = 0; k < vocabulary[key].length; k++) {
            if (unparsedArray.slice(i, j).join(' ').toLowerCase() ===
                vocabulary[key][k]) {
              // We have identified the next (j-i)-many words together form a
              // phrase in the vocabulary dictionary.
              for (var l = 0; l < partiallyParsedArrays[i].length; l++) {
                partiallyParsedArrays[j].push(
                  partiallyParsedArrays[i][l].concat([{
                    format: 'phrase',
                    content: key
                  }])
                );
              }
            }
          }
        }
      }

      // If something is a known word then we do not attempt to parse it as an
      // expression. This is because any word can be regarded as an expression
      // (as a single atom) so otherwise we would end up with a large number of
      // spurious parsings. The exception is single-character words, because
      // e.g. 'a' could reasonably be either a word or the name of an atom.
      if (unparsedArray[i].length === 1 ||
          vocabularyWords.indexOf(unparsedArray[i].toLowerCase()) === -1) {
        // We attempt to parse this entry as an expression / expression template
        try {
          var expression = logicProofParser.parse(
            unparsedArray[i], isTemplate ? 'expressionTemplate' : 'expression');
          for (var j = 0; j < partiallyParsedArrays[i].length; j++) {
            // We do not allow a line to have two expressions in a row. This is
            // to allow the identification of typos: For example if the user
            // types 'fron p∧q ...' then otherwise we would think that both
            // 'fron' and 'p∧q' are expressions. We also do not attempt to
            // parse a word as an expression if it is a vocabulary word, to
            // avoid masses of silly attempts to parse the line.
            if (i === 0 ||
                partiallyParsedArrays[i][j][
                  partiallyParsedArrays[i][j].length - 1
                ].format === 'phrase') {
              partiallyParsedArrays[i + 1].push(
                partiallyParsedArrays[i][j].concat([{
                  format: 'expression',
                  content: expression
                }])
              );
            }
          }
        } catch (err) {}
      }
    }

    if (partiallyParsedArrays[unparsedArray.length].length > 0) {
      // We have succeeded in fully parsing
      return partiallyParsedArrays[unparsedArray.length];
    } else {
      // We identify the best attempts
      for (var i = unparsedArray.length; i >= 0; i--) {
        if (partiallyParsedArrays[i].length > 0) {
          var numEntriesMatched = i;
          break;
        }
      }
      // We return a description of the problem, based on one of the best
      // attempts.
      // NOTE: This is not guaranteed to correctly identify the mistake the
      // user made. It could do with improvement based on user feedback.
      // containsLogicalCharacter is used to guess if something is an
      // expression, but it is not always correct because expressions may
      // consist only of letters.
      var bestAttempt = partiallyParsedArrays[numEntriesMatched][0];
      if (numEntriesMatched === 0 ||
          bestAttempt[bestAttempt.length - 1].format === 'phrase') {
        var word = unparsedArray[numEntriesMatched];
        throw (vocabularyWords.indexOf(word) !== -1) ?
          new UserError('unidentified_phrase_starting_at', {
            word: word
          }) :
          new UserError('unidentified_word', {
            word: word
          });
      } else {
        var word1 = unparsedArray[numEntriesMatched - 1];
        var word2 = unparsedArray[numEntriesMatched];
        if (vocabularyWords.indexOf(word1) !== -1) {
          throw new UserError('unidentified_phrase_starting_at', {
            word: word1
          });
        } else if (containsLogicalCharacter(word1, operators, isTemplate)) {
          throw (vocabularyWords.indexOf(word2) !== -1) ?
            new UserError('unidentified_phrase_starting_at', {
              word: word2
            }) :
            containsLogicalCharacter(word2, operators, isTemplate) ?
            new UserError('consecutive_expressions', {
              word1: word1,
              word2: word2
            }) :
            new UserError('unidentified_word', {
              word: word2
            });
        } else {
          throw (vocabularyWords.indexOf(word2) !== -1) ?
            new UserError('unidentified_phrase_starting_at', {
              word: word2
            }) :
            containsLogicalCharacter(word2, operators, isTemplate) ?
              new UserError('unidentified_word', {
                word: word1
              }) :
              new UserError('unidentified_words', {
                word1: word1,
                word2: word2
              });
        }
      }
    }
  };

  // TYPING ASSIGNMENT

  /**
   * This takes an array of TypingElements and converts it into an array of
   * types.
   * @param {Array.<Object>} types - an array of dictionaries of the form {
   *               type: the name of an available type ('boolean' or 'element')
   *               arbitrarily_many: boolean
   *            }
   *          where at most one member can have 'arbitrarily_many' set to
   *          true, signifying that any number of arguments of this type
   *          can occur here.
   * @param {int} desiredLength - the number of entries we would like to have.
   * @returns {array} an array of types with the right number of entries,
   *          derived from 'types'.
   * @throws if this is not possible.
   */
  var instantiateTypingElementArray = function(types, desiredLength) {
    var listOfTypes = [];
    for (var i = 0; i < types.length; i++) {
      listOfTypes.push(types[i].type);
      if (types[i].arbitrarily_many) {
        var indexWithArbitrarilyMany = i;
      }
    }
    if (indexWithArbitrarilyMany === undefined) {
      if (types.length === desiredLength) {
        return listOfTypes;
      } else {
        throw new UserError('wrong_num_inputs', {
          num_needed: desiredLength
        });
      }
    } else {
      var output = [];
      if (types.length <= desiredLength + 1) {
        for (var i = 0; i < types.length; i++) {
          if (i === indexWithArbitrarilyMany) {
            for (var j = 0; j < desiredLength - types.length + 1; j++) {
              output.push(listOfTypes[indexWithArbitrarilyMany]);
            }
          } else {
            output.push(listOfTypes[i]);
          }
        }
        return output;
      } else {
        throw new UserError('not_enough_inputs', {
          num_needed: desiredLength
        });
      }
    }
  };

  /**
   * This takes an (untyped) Expression, usually provided by the parser, and
   * returns a TypedExpression in which types have been added at each level.
   * @param {Expression} untypedExpression - the expression to be typed
   * @param {Array} possibleTopTypes - an array of types that the expression as
   *        a whole could have - each will be tried in turn.
   * @param {Language} language - the relevant language
   * @param {Array} newKindsPermitted - an array of kinds (e.g. 'variable',
   *        'constant') of which the user is allowed to create new operators.
   *        Any operator with a kind not in this list and that does not already
   *        occur in the language will cause an error.
   * @param {boolean} permitDuplicateDummyNames - if true the user can write
   *        e.g. ∀x.p even if x is already in use; if false they cannot.
   * @return {array} An array of dictionaries of the form: {
   *           typedExpression: A TypedExpression
   *           operators: the given language.operatorss together with any new
   *             operators that occurred in the expression.
   * @throws If a valid typing cannot be found this function will throw a
   *         UserError. The parameters of this error will contain an additional
   *         key 'amountTyped' that determines where the error occurred. e.g.
   *         [1,2,0] would indicate that there was a problem at the 0th input
   *         (dummy or argument) of the 2nd input of the 1st input of this
   *         expression. We return the typing attempt for which this  value is
   *         largest (in lexicographic ordering) as this is likely to be closest
   *         to what the user intended.
   */
  var assignTypesToExpression = function(untypedExpression, possibleTopTypes,
      language, newKindsPermitted, permitDuplicateDummyNames) {
    var operators = language.operators;
    newKindsPermitted = newKindsPermitted || ['constant', 'variable'];
    permitDuplicateDummyNames = permitDuplicateDummyNames || false;

    var _attemptTyping = function(topType, typingRule) {
      if (!operatorIsNew &&
          untypedExpression.top_kind_name !==
            operators[untypedExpression.top_operator_name].kind) {
        throw new UserError('wrong_kind', {
          operator: untypedExpression.top_operator_name,
          expected_kind: operators[untypedExpression.top_operator_name].kind,
          actual_kind: untypedExpression.top_kind_name,
          amount_typed: []
        });
      }
      if (topType !== typingRule.output) {
        throw new UserError('wrong_type', {
          operator: untypedExpression.top_operator_name,
          expected_type: topType,
          actual_type: typingRule.output,
          amount_typed: []
        });
      }

      var _isNumber = function(n) {
        return !isNaN(parseFloat(n)) && isFinite(n);
      };

      var _isString = function(s) {
        return s[0] === '\'' && s[s.length - 1] === '\'';
      };

      if (language.types.hasOwnProperty('integer') &&
          _isNumber(untypedExpression.top_operator_name) &&
          untypedExpression.top_kind_name === 'constant' &&
          topType !== 'integer') {
        throw new UserError('wrong_type', {
          operator: untypedExpression.top_operator_name,
          expected_type: topType,
          actual_type: 'integer',
          amount_typed: []
        });
      }
      if (language.types.hasOwnProperty('string') &&
          _isString(untypedExpression.top_operator_name) &&
          untypedExpression.top_kind_name === 'constant' &&
          topType !== 'string') {
        throw new UserError('wrong_type', {
          operator: untypedExpression.top_operator_name,
          expected_type: topType,
          actual_type: 'string',
          amount_typed: []
        });
      }

      try {
        var argumentTypes = instantiateTypingElementArray(
          typingRule.arguments, untypedExpression.arguments.length);
      } catch (err) {
        err.parameters.operator = untypedExpression.top_operator_name;
        err.parameters.input_category = 'arguments';
        err.parameters.amount_typed = [];
        throw err;
      }

      try {
        var dummyTypes = instantiateTypingElementArray(
          typingRule.dummies, untypedExpression.dummies.length);
      } catch (err) {
        err.parameters.operator = untypedExpression.top_operator_name;
        err.parameters.input_category = 'dummies';
        err.parameters.amount_typed = [];
        throw err;
      }
      var updatedOperators = {};
      for (key in operators) {
        updatedOperators[key] = operators[key];
      }
      if (operatorIsNew) {
        var _decorateTypes = function(types) {
          decoratedTypes = [];
          for (var k = 0; k < types.length; k++) {
            decoratedTypes.push({
              type: types[k],
              arbitrarily_many: false
            });
          }
          return decoratedTypes;
        };

        updatedOperators[untypedExpression.top_operator_name] = {
          kind: untypedExpression.top_kind_name,
          typing: [{
            arguments: _decorateTypes(argumentTypes),
            dummies: _decorateTypes(dummyTypes),
            output: topType
          }]
        };
      }

      for (var n = 0; n < untypedExpression.dummies.length; n++) {
        if (!permitDuplicateDummyNames &&
            updatedOperators.hasOwnProperty(
              untypedExpression.dummies[n].top_operator_name)) {
          throw new UserError('duplicate_dummy_name', {
            dummy: untypedExpression.dummies[n],
            expression: untypedExpression,
            amount_typed: []
          });
        } else if (untypedExpression.dummies[n].top_kind_name !== 'variable') {
          // The parser does not currently permit this to happen
          throw new UserError('dummy_not_variable', {
            dummy: untypedExpression.dummies[n],
            expression: untypedExpression,
            amount_typed: []
          });
        }
      }

      return assignTypesToExpressionArray(
        untypedExpression.dummies.concat(untypedExpression.arguments),
        dummyTypes.concat(argumentTypes), {
          operators: updatedOperators,
          kinds: language.kinds,
          types: language.types
        }, newKindsPermitted, permitDuplicateDummyNames,
        untypedExpression.dummies.length);
    };

    var operatorIsNew = false;
    if (!operators.hasOwnProperty(untypedExpression.top_operator_name)) {
      if (newKindsPermitted.indexOf(untypedExpression.top_kind_name) === -1) {
        throw new UserError('unknown_operator', {
          operator: untypedExpression.top_operator_name,
          amount_typed: []
        });
      } else {
        operatorIsNew = true;
      }
    }
    var typingRules = (operatorIsNew) ?
      language.kinds[untypedExpression.top_kind_name].typing :
      operators[untypedExpression.top_operator_name].typing;

    var results = [];
    for (var i = 0; i < possibleTopTypes.length; i++) {
      for (var j = 0; j < typingRules.length; j++) {
        try {
          var newAttempts = _attemptTyping(possibleTopTypes[i], typingRules[j]);
          for (var k = 0; k < newAttempts.length; k++) {
            var typedDummies = [];
            for (var l = 0; l < untypedExpression.dummies.length; l++) {
              typedDummies.push(newAttempts[k].typedArray[l]);
              // These dummy variables should not be available outside this
              // part of the untypedExpression.
              if (!operators.hasOwnProperty(
                    untypedExpression.dummies[l].top_operator_name)) {
                delete newAttempts[k].operators[
                  untypedExpression.dummies[l].top_operator_name];
              }
            }
            var typedArguments = [];
            for (var l = untypedExpression.dummies.length;
                 l < untypedExpression.dummies.length +
                     untypedExpression.arguments.length;
                 l++) {
              typedArguments.push(newAttempts[k].typedArray[l]);
            }

            results.push({
              typedExpression: {
                top_operator_name: untypedExpression.top_operator_name,
                top_kind_name: untypedExpression.top_kind_name,
                arguments: typedArguments,
                dummies: typedDummies,
                type: possibleTopTypes[i]
              },
              operators: newAttempts[k].operators
            });
          }
        } catch (err) {
          if (bestAttemptSoFar !== undefined &&
              !bestAttemptSoFar.hasOwnProperty('parameters')) {
            throw bestAttemptSoFar;
          }
          if (bestAttemptSoFar === undefined ||
              greaterThanInLex(
                err.parameters.amount_typed,
                bestAttemptSoFar.parameters.amount_typed)) {
            var bestAttemptSoFar = err;
          }
        }
      }
    }
    if (results.length > 0) {
      return results;
    } else {
      throw bestAttemptSoFar;
    }
  };

  /** Companion function to assignTypesToExpression, with the following
   * modifications:
   * @param untypedArray: an array of expressions to type
   *  @param topTypes: an array of types that the expressions in the array must
   *        have (only one option for each).
   * @numDummies: the number of elements in the array (from the start) that are
   *              dummies rather than arguments.
   * @result: {
   *            typedArray: an array of TypedExpressions
   *            operators: the updated list of operators
   *          }
   * @raises: as before
   */
  var assignTypesToExpressionArray = function(untypedArray, topTypes, language,
      newKindsPermitted, isTemplate, numDummies) {
    newKindsPermitted = newKindsPermitted || ['constant', 'variable'];
    isTemplate = isTemplate || false;
    numDummies = numDummies || 0;

    var partiallyTypedArrays = [[[]]];
    var partiallyUpdatedOperators = [[{}]];
    for (var key in language.operators) {
      partiallyUpdatedOperators[0][0][key] = language.operators[key];
    }
    for (var i = 1; i <= untypedArray.length; i++) {
      partiallyTypedArrays.push([]);
      partiallyUpdatedOperators.push([]);
    }

    for (var i = 0; i < untypedArray.length; i++) {
      // This will only happen in pathological cases.
      if (partiallyTypedArrays[i].length > MAX_NUM_TYPINGS_PERMITTED) {
        throw new UserError('too_many_typings', {});
      }

      for (var j = 0; j < partiallyTypedArrays[i].length; j++) {
        // Dummies are always allowed to have previously unseen names
        var newKindsPermittedHere = (i < numDummies) ?
          newKindsPermitted.concat(['variable']) :
          newKindsPermitted;
        try {
          var newResults = assignTypesToExpression(
            untypedArray[i], [topTypes[i]], {
              operators: partiallyUpdatedOperators[i][j],
              kinds: language.kinds,
              types: language.types
            }, newKindsPermittedHere, isTemplate);
          for (var k = 0; k < newResults.length; k++) {
            partiallyTypedArrays[i + 1].push(
              partiallyTypedArrays[i][j].concat([
                newResults[k].typedExpression]));
            partiallyUpdatedOperators[i + 1].push(newResults[k].operators);
          }
        } catch (err) {
          if (!err.hasOwnProperty('parameters')) {
            throw err;
          }
          var amountTyped = [i].concat(err.parameters.amount_typed);
          if (bestAttemptSoFar === undefined ||
              greaterThanInLex(
                amountTyped, bestAttemptSoFar.parameters.amount_typed)) {
            err.parameters.amount_typed = amountTyped;
            var bestAttemptSoFar = err;
          }
        }
      }
    }
    var fullyTypedArrays = partiallyTypedArrays[untypedArray.length];
    var fullyUpdatedOperatorss = partiallyUpdatedOperators[
    untypedArray.length];
    if (fullyTypedArrays.length > 0) {
      var result = [];
      for (var i = 0; i < fullyTypedArrays.length; i++) {
        result.push({
          typedArray: fullyTypedArrays[i],
          operators: fullyUpdatedOperatorss[i]
        });
      }
      return result;
    } else {
      throw bestAttemptSoFar;
    }
  };

  // UTILITIES

  // Expressions with different dummy variables are considered different
  var checkExpressionsAreEqual = function(expression1, expression2) {
    if (expression1.top_kind_name !== expression2.top_kind_name ||
        expression1.top_operator_name !== expression2.top_operator_name ||
        expression1.arguments.length !== expression2.arguments.length ||
        expression1.dummies.length !== expression2.dummies.length) {
      return false;
    }
    if (expression1.hasOwnProperty('type')) {
      if (expression1.type !== expression2.type) {
        return false;
      }
    }
    for (var i = 0;
         i < expression1.arguments.length + expression1.dummies.length; i++) {
      if (!checkExpressionsAreEqual(
          (expression1.arguments.concat(expression1.dummies))[i],
          (expression2.arguments.concat(expression2.dummies))[i])) {
        return false;
      }
    }
    return true;
  };

  var checkExpressionIsInSet = function(expression, set) {
    for (var i = 0; i < set.length; i++) {
      if (checkExpressionsAreEqual(expression, set[i])) {
        return true;
      }
    }
    return false;
  };

  var checkSetsOfExpressionsAreEqual = function(set1, set2) {
    for (var i = 0; i < set1.length; i++) {
      if (!checkExpressionIsInSet(set1[i], set2)) {
        return false;
      }
    }
    for (var i = 0; i < set2.length; i++) {
      if (!checkExpressionIsInSet(set2[i], set1)) {
        return false;
      }
    }
    return true;
  };

  // Returns a list of all the names of operators in an expression. kinds is an
  // array specifying which kinds of operators to return; if it is not supplied
  // then all are returned
  var getOperatorsFromExpression = function(expression, kinds) {
    kinds = kinds || false;
    var output = getOperatorsFromExpressionArray(
      expression.arguments.concat(expression.dummies), kinds);
    return (output.indexOf(expression.top_operator_name) === -1 &&
        (kinds === false || kinds.indexOf(expression.top_kind_name) !== -1)) ?
      output.concat([expression.top_operator_name]) :
      output;
  };

  var getOperatorsFromExpressionArray = function(array, kinds) {
    kinds = kinds || false;
    var output = [];
    for (var i = 0; i < array.length; i++) {
      var newOutput = getOperatorsFromExpression(array[i], kinds);
      for (var j = 0; j < newOutput.length; j++) {
        if (output.indexOf(newOutput[j]) === -1) {
          output = output.concat([newOutput[j]]);
        }
      }
    }
    return output;
  };

  // The expression should be typed; returns the type of operator (or throws an
  // error if not found). Does not check for inconsistent typing.
  // NOTE: treats dummy variables like free ones.
  var seekTypeInExpression = function(expression, operator) {
    return operator === expression.top_operator_name ? expression.type :
      seekTypeInExpressionArray(
        expression.arguments.concat(expression.dummies), operator);
  };

  var seekTypeInExpressionArray = function(array, operator) {
    for (var i = 0; i < array.length; i++) {
      try {
        return seekTypeInExpression(array[i], operator);
      } catch (err) {}
    }
    throw UserError('unknown_typing_error', {
      expression: expression
    });
  };

  // Returns whether LHS is larger than RHS in lexicographic ordering
  var greaterThanInLex = function(LHS, RHS) {
    for (var i = 0; i < LHS.length; i++) {
      if (i >= RHS.length) {
        return true;
      } else if (LHS[i] > RHS[i]) {
        return true;
      } else if (LHS[i] < RHS[i]) {
        return false;
      }
    }
    return false;
  };

  // Checks if the string contains the character
  var containsCharacter = function(string, character) {
    return (string.indexOf(character) !== -1);
  };

  // Checks if the string contains some character from the array
  var containsCharacterFromArray = function(string, array) {
    for (var i = 0; i < array.length; i++) {
      if (string.indexOf(array[i]) !== -1) {
        return true;
      }
    }
    return false;
  };

  return {
    UserError: UserError,
    PreRenderedUserError: PreRenderedUserError,
    renderError: renderError,
    displayExpression: displayExpression,
    displayExpressionArray: displayExpressionArray,
    preParseLineString: preParseLineString,
    parseLineString: parseLineString,
    instantiateTypingElementArray: instantiateTypingElementArray,
    assignTypesToExpression: assignTypesToExpression,
    assignTypesToExpressionArray: assignTypesToExpressionArray,
    checkExpressionsAreEqual: checkExpressionsAreEqual,
    checkExpressionIsInSet: checkExpressionIsInSet,
    checkSetsOfExpressionsAreEqual: checkSetsOfExpressionsAreEqual,
    getOperatorsFromExpression: getOperatorsFromExpression,
    getOperatorsFromExpressionArray: getOperatorsFromExpressionArray,
    seekTypeInExpression: seekTypeInExpression,
    greaterThanInLex: greaterThanInLex
  };
})();


text:
#pragma once

#include "Photon-cpp/inc/PhotonPeer.h"

namespace ExitGames
{
	namespace Chat
	{

		/**
			Callback interface for Chat client side. Contains callback methods to notify your app about updates.
			Must be provided to new Chat::Client in constructor*/
		class Listener: public Common::BaseListener
		{
		public:
			virtual ~Listener(void){}

			// receive and print out debug out here
			virtual void debugReturn(Common::DebugLevel::DebugLevel debugLevel, const Common::JString& string) = 0;

			/**
				Notifies app that client state changed.
				@param state new client state
				@sa ClientState::ClientState*/
			virtual void onStateChange(int state) = 0;

			// implement your error-handling here
			virtual void connectionErrorReturn(int errorCode) = 0;
			virtual void clientErrorReturn(int errorCode) = 0;
			virtual void warningReturn(int warningCode) = 0;
			virtual void serverErrorReturn(int errorCode) = 0;

			// callbacks for operations on server

			/**
				Client is connected now.*/
			virtual void connectReturn(int errorCode, const Common::JString& errorString) = 0;

			/**
				Disconnection happened.*/
			virtual void disconnectReturn(void) = 0;

			/**
				Result of subscribe operation. Returns per channel name if the channel is now subscribed.
				@param channels channel names
				@param per channel result: true if subscribed*/
			virtual void subscribeReturn(const Common::JVector<Common::JString>& channels, const Common::JVector<bool>& results) = 0;

			/**
				Result of unsubscribe operation. Returns per channel name if the channel is now subscribed.
				@param channels channel names that are no longer subscribed*/
			virtual void unsubscribeReturn(const Common::JVector<Common::JString>& channels) = 0;

			/**
				New status of another user (you get updates for users set in your friends list).
				@param user name of the user
				@param status new status of that user
				@param gotMessage true if the status contains a message you should cache locally. False: This status update does not include a message (keep any you have).
				@param message message that user set*/
			virtual void onStatusUpdate(const Common::JString& user, int status, bool gotMessage, const Common::Object& message) = 0;

			/**
				Notifies app that client got new messages from server
				Number of senders is equal to number of messages in 'messages'. Sender with number '0' corresponds to message with
				number '0', sender with number '1' corresponds to message with number '1' and so on
				@param channelName channel from where messages came
				@param senders list of users who sent messages
				@param messages list of messages it self*/
			virtual void onGetMessages(const Common::JString& channelName, const Common::JVector<Common::JString>& senders, const Common::JVector<Common::Object>& messages) = 0;

			/**
				Notifies client about private message
				@param name sender user who sent this message
				@param name message message it self
				@param name channelName channel name for private messages (messages you sent yourself get added to a channel per target username)*/
			virtual void onPrivateMessage(const Common::JString& sender, const Common::Object& message, const Common::JString& channelName) = 0;
		};
		/** @file */
	}
}


text:
module.exports = {
  '@desiredCapabilities': {
    name: 'test-Name'
  },
  demoTest: function (client) {
    client.assert.equal(client.options.desiredCapabilities.name, 'test-Name');

    client.url('http://localhost')
      .assert.elementPresent('#weblogin');
  },

  after: function (client) {
    client.end();
  }
};