// Возвращает список папок из "/Source/Urho3D/", отбрасывая лишние.
    static string[] НужныеПапки(string путь)
    {
        string[]      папки     = Directory.GetDirectories(путь);
        List <string> результат = new List <string>(папки.Length);

        foreach (string папка in папки)
        {
            if (!игнорируемыеПапки.Contains(Утилиты.ИмяПапки(папка)))
            {
                результат.Add(папка);
            }
        }
        return(результат.ToArray());
    }
    static void Main(string[] аргументы)
    {
        foreach (string папка in НужныеПапки(PATH))
        {
            // Создаем папку в текущей.
            string имяПапки = Утилиты.ИмяПапки(папка);
            if (!Directory.Exists("DotNet/" + имяПапки))
            {
                Directory.CreateDirectory("DotNet/" + имяПапки);
            }
            foreach (string файл in НужныеФайлы(папка))
            {
                Console.WriteLine(файл);

                string оригинальныйИсходник    = File.ReadAllText(файл);
                string преобразованныйИсходник = ЗаголовочныйФайл.Преобразовать(оригинальныйИсходник);

                string имяФайла = Path.GetFileName(файл);
                имяПапки = Утилиты.ИмяПапки(файл);
                File.WriteAllText("DotNet/" + имяПапки + "/" + имяФайла, преобразованныйИсходник);
            }
        }
    }
    public string ПреобразоватьФункцию(string исходник)
    {
        исходник = исходник.Replace("\n", " ");
        if (исходник.StartsWith("URHO3D_OBJECT"))
        {
            return(исходник);
        }
        if (исходник.Contains("operator"))
        {
            return(исходник);
        }
        if (исходник.Contains("~"))
        {
            return(исходник);
        }

        string результат = "// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";

        результат += "// " + исходник + "\n";

        // Возможно это функция с телом.
        string шаблон       = @"([^:;(){}]+)\(([^;(){}]*)\)\s*(?:const)?\s*(?:override)?\s*{.*?}";
        Match  соответствие = Regex.Match(исходник, шаблон, RegexOptions.Singleline);

        if (!соответствие.Success)
        {
            // Значит функция без тела.
            шаблон       = @"([^:;(){}]+)\(([^;(){}]*)\)\s*(?:const)?\s*(?:override)?\s*;";
            соответствие = Regex.Match(исходник, шаблон, RegexOptions.Singleline);
        }
        string передСкобками = соответствие.Result("$1"); // Возвращаемый тип + имя функции.
        string параметры     = соответствие.Result("$2"); // Параметры в скобках.

        шаблон       = @"(.*?)\s*(~?\w+)\s*$";
        соответствие = Regex.Match(передСкобками, шаблон, RegexOptions.Singleline);
        string возвращаемыйТип = соответствие.Result("$1");
        string имяФункции      = соответствие.Result("$2");

        string имяКласса = Имя;

        // Для отладки.
        результат += "// КЛАСС = " + имяКласса + ", ВОЗВРАЩАЕМЫЙ ТИП = " + возвращаемыйТип + ", ИМЯ = " + имяФункции + ", ПАРАМЕТРЫ = " + параметры + "\n";

        результат += "// C++\n";
        результат += "URHO3D_API ";

        // Это вставим в результат позже, но формируем сразу.
        string заголовок_CSharp = "private static extern ";

        // Возвращаемый тип.
        bool конструктор = false; // Функция является конструктором.

        if (имяКласса == имяФункции)
        {
            конструктор = true;
        }
        if (конструктор)
        {
            результат        += имяКласса + "* ";
            заголовок_CSharp += "IntPtr ";
        }
        else
        {
            результат        += возвращаемыйТип + " ";
            заголовок_CSharp += возвращаемыйТип + " ";
        }

        // Имя обертки.
        результат        += Имя + "_" + имяФункции;
        результат        += "(";
        заголовок_CSharp += Имя + "_" + имяФункции;
        заголовок_CSharp += "(";

        // Параметры обертки.
        параметры = Утилиты.УдалитьПовтороныеПробелы(параметры).Trim();
        параметры = параметры.Replace("Context* context", "Context* nativeContext");
        параметры = параметры.Replace("String::EMPTY", "\"\"");
        параметры = параметры.Replace("const String&", "const char*");
        if (конструктор)
        {
            результат        += параметры + ")\n";
            заголовок_CSharp += параметры + ");\n";
        }
        else
        {
            if (параметры == "")
            {
                результат        += Имя + "* nativeInstance)\n";
                заголовок_CSharp += "IntPtr nativeInstance);\n";
            }
            else
            {
                результат        += Имя + "* nativeInstance, " + параметры + ")\n";
                заголовок_CSharp += "IntPtr nativeInstance, " + параметры + ");\n";
            }
        }

        // Тело обертки.
        результат += "{\n";
        if (конструктор)
        {
            результат += "    return new " + имяКласса + "(" + параметры + ");\n";
        }
        else
        {
            if (возвращаемыйТип.Contains("void"))
            {
                результат += "    ";
            }
            else
            {
                результат += "    return ";
            }
            результат += "nativeInstance->" + имяФункции + "(" + УбратьТипыПараметров(параметры) + ");\n";
        }
        результат += "}\n";

        // C# код.
        результат       += "// C#\n";
        результат       += "[DllImport(Consts.NativeLibName, CallingConvention = CallingConvention.Cdecl)]\n";
        заголовок_CSharp = заголовок_CSharp.Replace("const char*", "string");
        результат       += УказателиВIntPtr(заголовок_CSharp);

        return(результат + "\n\n");
    }