public static void Parse(List<string> files, ErrorCollection errors)
        {
            /*
             * #macro <identifier>[(<identifiers>)]
             * anything...#arg1...anything
             *
             * #endmacro
             *
             * #<identifier>(anything_but_comma, #anything_but_hash#)
             *
             *
             */

            //Phase 1: locate all macros
            List<Macro> macros = new List<Macro>();
            for (int i = 0; i < files.Count; i++)
            {
                string source = files[i];

                Lexer lexer = new Lexer(new StringReader(source));
                List<Token> tokens = new List<Token>();
                Token token;
                while (!((token = lexer.Next()) is EOF))
                {
                    if (token is TWhiteSpace || token is TTraditionalComment || token is TDocumentationComment || token is TEndOfLineComment)
                        continue;
                    tokens.Add(token);
                }

                List<Util.Pair<TextPoint, TextPoint>> macroSpan = new List<Util.Pair<TextPoint, TextPoint>>();

                for (int j = 0; j < tokens.Count - 1; j++)
                {
                    int t = j;
                    if (tokens[t] is TSharp && tokens[t + 1].Text == "macro")
                    {
                        Macro macro = new Macro();
                        Token sharp = tokens[t];
                        macro.token = sharp;
                        TextPoint start = TextPoint.FromCompilerCoords(tokens[t]);
                        t += 2;
                        if (t >= tokens.Count || !(tokens[t] is TIdentifier))
                        {
                            errors.Add(new ErrorCollection.Error(sharp, LocRM.GetString("ErrorText206")));
                            continue;
                        }
                        macro.Name = tokens[t].Text;
                        //Find end
                        TextPoint end = new TextPoint(-1, -1);
                        for (int k = t; k < tokens.Count - 1; k++)
                        {
                            if (tokens[k] is TSharp)
                            {
                                if (tokens[k + 1].Text == "macro")
                                {
                                    errors.Add(new ErrorCollection.Error(tokens[k],
                                                                         LocRM.GetString("ErrorText207"),
                                                                         false,
                                                                         new ErrorCollection.Error(sharp,
                                                                                                   LocRM.GetString("ErrorText208"))));
                                }
                                else if (tokens[k + 1].Text == "endmacro")
                                {
                                    end = TextPoint.FromCompilerCoords(tokens[k]);
                                    break;
                                }
                            }
                        }
                        if (end.Line == -1)
                        {
                            errors.Add(new ErrorCollection.Error(sharp, LocRM.GetString("ErrorText209")));
                            continue;
                        }
                        //Check for parameters
                        t++;
                        TextPoint textStart;
                        if (tokens[t] is TLParen)
                        {
                            macro.Method = true;
                            bool needComma = false;
                            while (true)
                            {
                                t++;
                                if (tokens[t] is TRParen)
                                    break;
                                if (tokens[t] is TComma)
                                {
                                    if (!needComma)
                                    {
                                        errors.Add(new ErrorCollection.Error(tokens[t], LocRM.GetString("ErrorText210")));
                                        break;
                                    }
                                    needComma = false;
                                    t++;
                                }
                                if (tokens[t] is TIdentifier)
                                {
                                    if (needComma)
                                    {
                                        errors.Add(new ErrorCollection.Error(tokens[t], LocRM.GetString("ErrorText211")));
                                        break;
                                    }
                                    macro.Parameters.Add(tokens[t].Text);
                                    needComma = true;
                                    continue;
                                }
                                if (needComma)
                                    errors.Add(new ErrorCollection.Error(tokens[t], LocRM.GetString("ErrorText211")));
                                else
                                    errors.Add(new ErrorCollection.Error(tokens[t], LocRM.GetString("ErrorText210")));
                                break;
                            }
                            textStart = TextPoint.FromCompilerCoords(tokens[t]);
                            textStart.Pos++;
                            t++;
                        }
                        else
                        {
                            textStart = TextPoint.FromCompilerCoords(tokens[t - 1]);
                            textStart.Pos += macro.Name.Length;
                        }

                        macro.Text = GetText(source, textStart, end);
                        macroSpan.Add(new Util.Pair<TextPoint, TextPoint>(start, end));
                        macros.Add(macro);
                        j = t;
                    }
                }

                //Remove macros
                List<string> lines = source.Split('\n').ToList();
                for (int j = macroSpan.Count - 1; j >= 0; j--)
                {
                    TextPoint start = macroSpan[j].First;
                    TextPoint end = macroSpan[j].Second;

                    lines[start.Line] = lines[start.Line].Substring(0, start.Pos - 1) + lines[end.Line].Substring(end.Pos + "#endmacro".Length - 1);
                    for (int line = end.Line; line > start.Line; line--)
                    {
                        lines.RemoveAt(line);
                    }
                }

                StringBuilder builder = new StringBuilder();
                builder.Append(lines[0]);
                for (int j = 0; j < lines.Count; j++)
                {
                    builder.Append("\n" + lines[j]);
                }
                source = builder.ToString();

                files[i] = source;
            }

            //Check for dublicate macros
            for (int i = 0; i < macros.Count; i++)
            {
                List<Macro> conflicts = new List<Macro>(){macros[i]};
                for (int j = i + 1; j < macros.Count; j++)
                {
                    if (macros[i].Name == macros[j].Name &&
                        macros[i].Method == macros[j].Method &&
                        macros[i].Parameters.Count == macros[j].Parameters.Count)
                        conflicts.Add(macros[j]);
                }
                if (conflicts.Count > 1)
                {
                    List<ErrorCollection.Error> subErrors = new List<ErrorCollection.Error>();
                    foreach (Macro macro in conflicts)
                    {
                        subErrors.Add(new ErrorCollection.Error(macro.token, LocRM.GetString("ErrorText212")));
                        macros.Remove(macro);
                    }
                    errors.Add(new ErrorCollection.Error(conflicts[0].token, LocRM.GetString("ErrorText213"), false, subErrors.ToArray()));
                    i--;
                }
            }

            //Search for macro invocations

            for (int i = 0; i < files.Count; i++)
            {
                string source = files[i];
                ReplaceInvocations(ref source, macros, new List<Macro>(), errors);
                files[i] = source;
            }
        }
        private static void ReplaceInvocations(ref string source, List<Macro> macros, List<Macro> currentReplacePath, ErrorCollection errors)
        {
            Lexer lexer = new Lexer(new StringReader(source));
            List<Token> tokens = new List<Token>();
            Token token;
            while (!((token = lexer.Next()) is EOF))
            {
                if (token is TWhiteSpace || token is TTraditionalComment || token is TDocumentationComment || token is TEndOfLineComment)
                    continue;
                tokens.Add(token);
            }

            List<Util.Pair<Util.Pair<TextPoint, TextPoint>, string>> macroSpan = new List<Util.Pair<Util.Pair<TextPoint, TextPoint>, string>>();

            for (int j = 0; j < tokens.Count - 1; j++)
            {
                int t = j;
                if (tokens[t] is TSharp && tokens[t + 1] is TIdentifier)
                {
                    Token sharp = tokens[t];
                    TextPoint start = TextPoint.FromCompilerCoords(tokens[t]);
                    t++;
                    string Name = tokens[t].Text;
                    //Check for parameters
                    t++;
                    bool IsMethod = false;
                    List<string> arguments = new List<string>();
                    TextPoint end;
                    if (tokens[t] is TLParen)
                    {
                        IsMethod = true;
                        int parens = 1;
                        TextPoint argStart = TextPoint.FromCompilerCoords(tokens[t + 1]);
                        while (true)
                        {
                            t++;
                            if (t >= tokens.Count)
                            {
                                errors.Add(new ErrorCollection.Error(sharp, LocRM.GetString("ErrorText214")));
                                t--;
                                break;
                            }

                            if (tokens[t] is TLParen || tokens[t] is TLBrace || tokens[t] is TLBracket)
                                parens++;
                            if (tokens[t] is TRParen || tokens[t] is TRBrace || tokens[t] is TRBracket)
                                parens--;
                            if (parens == 0)
                            {
                                if (!(tokens[t] is TRParen))
                                    errors.Add(new ErrorCollection.Error(tokens[t], LocRM.GetString("ErrorText215")));
                                if (!(tokens[t - 1] is TLParen))
                                {
                                    TextPoint e = TextPoint.FromCompilerCoords(tokens[t]);
                                    e.Pos++;
                                    arguments.Add(GetText(source, argStart, e));
                                }

                                break;
                            }
                            if (parens > 1)
                                continue;
                            if (tokens[t] is TComma)
                            {
                                TextPoint e = TextPoint.FromCompilerCoords(tokens[t]);
                                e.Pos++;
                                arguments.Add(GetText(source, argStart, e));
                                argStart = e;
                            }
                        }
                        end = TextPoint.FromCompilerCoords(tokens[t]);
                        end.Pos++;
                    }
                    else
                    {
                        end = TextPoint.FromCompilerCoords(tokens[t - 1]);
                        end.Pos += Name.Length;
                    }

                    bool found = false;
                    foreach (Macro macro in macros)
                    {
                        if (macro.Name == Name &&
                            macro.Method == IsMethod &&
                            macro.Parameters.Count == arguments.Count)
                        {
                            found = true;
                            if (currentReplacePath.Contains(macro))
                            {
                                List<ErrorCollection.Error> subErrors = new List<ErrorCollection.Error>();
                                for (int i = currentReplacePath.IndexOf(macro); i < currentReplacePath.Count; i++)
                                {
                                    subErrors.Add(new ErrorCollection.Error(currentReplacePath[i].token, LocRM.GetString("ErrorText216")));
                                }
                                errors.Add(new ErrorCollection.Error(sharp, LocRM.GetString("ErrorText217"), false, subErrors.ToArray()));
                                break;
                            }
                            string macroText = macro.GetText(arguments);
                            List<Macro> newCurrentPath = new List<Macro>();
                            newCurrentPath.AddRange(currentReplacePath);
                            newCurrentPath.Add(macro);
                            ReplaceInvocations(ref macroText, macros, newCurrentPath, errors);
                            macroSpan.Add(new Util.Pair<Util.Pair<TextPoint, TextPoint>, string>(new Util.Pair<TextPoint, TextPoint>(start, end), macroText));
                        }
                    }
                    if (!found)
                        errors.Add(new ErrorCollection.Error(sharp, LocRM.GetString("ErrorText218")));
                    j = t - 1;
                }
            }

            //Remove macros
            for (int i = macroSpan.Count - 1; i >= 0; i--)
            {
                List<string> lines = source.Split('\n').ToList();
                TextPoint start = macroSpan[i].First.First;
                TextPoint end = macroSpan[i].First.Second;
                string text = macroSpan[i].Second;

                lines[start.Line] = lines[start.Line].Substring(0, start.Pos - 1) + text + lines[end.Line].Substring(end.Pos - 1);
                for (int line = end.Line; line > start.Line; line--)
                {
                    lines.RemoveAt(line);
                }

                StringBuilder builder = new StringBuilder();
                builder.Append(lines[0]);
                for (int j = 0; j < lines.Count; j++)
                {
                    builder.Append("\n" + lines[j]);
                }
                source = builder.ToString();
            }
        }
        public void CompileLibrary(DirectoryInfo libraryDir, StreamWriter writer)
        {
            AAProgram root = new AAProgram();
            ErrorCollection errors = new ErrorCollection();

            foreach (FileInfo file in GetSourceFiles(libraryDir))
            {
                //Replace keywords
                StreamReader reader = file.OpenText();
                StringBuilder text = new StringBuilder("");
                string[] keywords = new[] {"ref", "out", "InvokeSync", "InvokeAsync",
                                                  "switch", "case", "default", "new", "delete", "this","delegate", "value", "base",
                "inline", "namespace", "using",
                                                                           "Trigger", "Initializer",
                                                                           "events", "conditions", "actions", "class",
                                                                           "typedef", "get", "set", "enrich",
                                                                           "public", "private", "protected",
                "LibraryName", "LibraryVersion", "SupportedVersions", "RequiredLibraries", "global"};

                int i;
                StringBuilder currentIdentifier = new StringBuilder("");
                while ((i = reader.Read()) != -1)
                {
                    if (Util.IsIdentifierLetter((char)i))
                    {
                        currentIdentifier.Append((char)i);
                    }
                    else
                    {
                        if (currentIdentifier.Length > 0)
                        {
                            string identifier = currentIdentifier.ToString();
                            currentIdentifier.Clear();
                            if (keywords.Contains(identifier))
                            {
                                identifier = "_" + identifier;
                            }
                            text.Append(identifier);
                        }
                        text.Append((char) i);
                    }
                }

                Parser parser = new Parser(new Lexer(new StringReader(text.ToString())));
                try
                {
                    Start start = parser.Parse();
                    AASourceFile srcFile = (AASourceFile) start.GetPSourceFile();
                    srcFile.SetName(new TIdentifier(file.FullName.Substring(libraryDir.FullName.Length + 1)));
                    root.GetSourceFiles().Add(srcFile);
                }
                catch (ParserException err)
                {
                    errors.Add(new ErrorCollection.Error(err.Token, file.Name, err.Message, false));
                }
                reader.Close();
            }

            try
            {
                Weeder.Parse(root, errors, new SharedData());
                LibraryData lib = new LibraryData(root, writer);
                FileInfo precompFile = new FileInfo(libraryDir.FullName + "\\Precompiled.LibraryData");
                IFormatter formatter = new BinaryFormatter();
                Stream stream = precompFile.Open(FileMode.Create);
                formatter.Serialize(stream, lib);
                stream.Close();
            }
            catch (Exception err)
            {

            }
            if (errors.HasErrors)
                MessageBox.Show("Errors in libray " + libraryDir.Name);
        }
        private void CompileThread()
        {
            Thread.CurrentThread.CurrentCulture = new CultureInfo(Form1.Language);
            Thread.CurrentThread.CurrentUICulture = new CultureInfo(Form1.Language);
            try
            {
                if (!compilingFromCommandLine)
                    form.SetStatusText(LocRM.GetString("GC_Text3"));

                if (!compilingFromCommandLine)
                    ClearErrorWindow();
                //Build a tree with all sourcefiles
                AAProgram root = new AAProgram();
                ErrorCollection errors = new ErrorCollection();
                currentErrorCollection = errors;
                if (!compilingFromCommandLine)
                    errors.ErrorAdded += errors_ErrorAdded;
                bool addedDeobfuscator = false;
                SharedData sharedData = new SharedData();
                sharedData.AllowPrintouts = !compilingFromCommandLine;
                //Parse project files
                List<string> fileNames = new List<string>();
                List<string> sources = new List<string>();
                foreach (
                    FileItem sourceFile in Form1.GetSourceFiles(ProjectProperties.CurrentProjectPropperties.SrcFolder))
                {
                    if (sourceFile.Deactivated)
                        continue;
                    StreamReader reader = sourceFile.File.OpenText();

                    string filename = sourceFile.File.FullName;
                    //Remove c:/.../projectDir/src
                    filename = filename.Remove(0, (ProjectDir.FullName + "/src/").Length);
                    //Remove .galaxy++
                    filename = filename.Remove(filename.Length - ".galaxy++".Length);
                    fileNames.Add(filename);
                    sources.Add(reader.ReadToEnd());
                    reader.Close();
                    continue;

                    Parser parser = new Parser(new Lexer(reader));
                    try
                    {
                        Start start = parser.Parse();
                        AASourceFile sourceNode = (AASourceFile) start.GetPSourceFile();
                        reader.Close();
                        reader = sourceFile.File.OpenText();
                        int lineCount = 0;
                        while (reader.ReadLine() != null)
                        {
                            lineCount++;
                        }
                        reader.Close();
                        sharedData.LineCounts[sourceNode] = lineCount;

                        //Extract encryption function
                       /* {
                            AASourceFile file = (AASourceFile) start.GetPSourceFile();
                            if (file.GetDecl().Count > 0 && file.GetDecl()[0] is AMethodDecl)
                            {
                                AMethodDecl method = (AMethodDecl) file.GetDecl()[0];
                                if (method.GetName().Text == "Galaxy_pp_Deobfuscate")
                                {
                                    FileInfo dobfuscateFile = new FileInfo("Deobfuscator.LibraryData");
                                    IFormatter formatter = new BinaryFormatter();
                                    Stream stream = dobfuscateFile.Open(FileMode.Create);
                                    formatter.Serialize(stream, method);
                                    stream.Close();
                                }
                            }
                        }*/

                        if (Options.Compiler.ObfuscateStrings)
                        {
                            HasStringConstExp checker = new HasStringConstExp();
                            start.Apply(checker);

                            if (!addedDeobfuscator /* && checker.HasStringConst*/)
                            {
                                FileInfo dobfuscateFile = new FileInfo("Deobfuscator.LibraryData");
                                IFormatter formatter = new BinaryFormatter();
                                Stream stream = dobfuscateFile.Open(FileMode.Open);
                                AASourceFile file = (AASourceFile) start.GetPSourceFile();

                                AMethodDecl method = (AMethodDecl) formatter.Deserialize(stream);
                                sharedData.DeobfuscateMethod = method;
                                method.GetName().Line = 0;

                                HasStringConstExp checker2 = new HasStringConstExp();
                                method.Apply(checker2);
                                file.GetDecl().Insert(0, method);
                                stream.Close();

                                addedDeobfuscator = true;

                                foreach (AStringConstExp stringConstExp in checker2.List)
                                {
                                    int line = -sharedData.UnobfuscatedStrings.Count - 1;
                                    AFieldDecl field = new AFieldDecl(new APublicVisibilityModifier(), null, new TConst("const", line, 0),
                                                                      new ANamedType(new TIdentifier("string", line, 1),
                                                                                     null),
                                                                      new TIdentifier("Galaxy_pp_stringU" +
                                                                                      sharedData.UnobfuscatedStrings.
                                                                                          Count),
                                                                      null);
                                    //If the strings are the same - point them to same field
                                    bool newField = true;
                                    foreach (AStringConstExp oldStringConstExp in sharedData.UnobfuscatedStrings.Keys)
                                    {
                                        if (stringConstExp.GetStringLiteral().Text ==
                                            oldStringConstExp.GetStringLiteral().Text)
                                        {
                                            field = sharedData.UnobfuscatedStrings[oldStringConstExp];
                                            newField = false;
                                            break;
                                        }
                                    }
                                    if (newField)
                                    {
                                        file.GetDecl().Insert(0, field);
                                        sharedData.ObfuscationFields.Add(field);
                                    }
                                    sharedData.UnobfuscatedStrings.Add(stringConstExp, field);

                                }

                            }
                            foreach (AStringConstExp stringConstExp in checker.List)
                            {
                                int line = -sharedData.ObfuscatedStrings.Count - 1;
                                AFieldDecl field = new AFieldDecl(new APublicVisibilityModifier(), null, new TConst("const", line, 0),
                                                                  new ANamedType(new TIdentifier("string", line, 1),
                                                                                 null),
                                                                  new TIdentifier("Galaxy_pp_stringO" +
                                                                                  sharedData.ObfuscatedStrings.Count),
                                                                  null);
                                //If the strings are the same - point them to same field
                                bool newField = true;
                                foreach (AStringConstExp oldStringConstExp in sharedData.ObfuscatedStrings.Keys)
                                {
                                    if (stringConstExp.GetStringLiteral().Text ==
                                        oldStringConstExp.GetStringLiteral().Text)
                                    {
                                        field = sharedData.ObfuscatedStrings[oldStringConstExp];
                                        newField = false;
                                        break;
                                    }
                                }
                                if (newField)
                                {
                                    AASourceFile file = (AASourceFile) sharedData.DeobfuscateMethod.Parent();
                                    file.GetDecl().Insert(file.GetDecl().IndexOf(sharedData.DeobfuscateMethod) + 1,
                                                          field);
                                    sharedData.ObfuscationFields.Add(field);
                                }
                                sharedData.ObfuscatedStrings.Add(stringConstExp, field);
                            }
                        }

                        sourceNode.SetName(new TIdentifier(filename));
                        root.GetSourceFiles().Add(start.GetPSourceFile());

                    }
                    catch (ParserException err)
                    {
                        String errMsg = err.Message;
                        //Remove [...]
                        errMsg = errMsg.Substring(errMsg.IndexOf(']') + 1).TrimStart();
                        errors.Add(new ErrorCollection.Error(err.Token, filename, errMsg));
                    }
                    reader.Close();
                }
                //Parse project dialogs
                foreach (
                    DialogItem dialogItem in Form1.GetDialogsFiles(ProjectProperties.CurrentProjectPropperties.SrcFolder))
                {
                    if (dialogItem.Deactivated)
                        continue;
                   // List<string> fileNames = new List<string>();
                   // List<string> sources = new List<string>();

                    DialogData data;
                    if (dialogItem.OpenFileData != null)
                    {
                        data = dialogItem.OpenFileData;
                        data.Save(dialogItem.FullName);
                    }
                    else
                    {
                        data = DialogData.Load(dialogItem.FullName);
                        data.DialogItem = dialogItem;
                    }

                    string filename = dialogItem.FullName;
                    filename = filename.Remove(0, (ProjectDir.FullName + "/src/").Length);
                    filename = filename.Remove(filename.Length - ".Dialog".Length);

                    fileNames.Add(filename);
                    sources.Add(data.Code ?? "");

                    fileNames.Add(filename + ".Designer");
                    sources.Add(data.DesignerCode ?? "");

                    continue;

                    for (int i = 0; i < fileNames.Count; i++)
                    {
                        filename = fileNames[i];
                        StringReader reader = new StringReader(sources[i] ?? "");
                        Parser parser = new Parser(new Lexer(reader));
                        try
                        {
                            Start start = parser.Parse();
                            AASourceFile sourceNode = (AASourceFile) start.GetPSourceFile();
                            reader.Close();
                            reader.Dispose();
                            reader = new StringReader(sources[i] ?? "");
                            int lineCount = 0;
                            while (reader.ReadLine() != null)
                            {
                                lineCount++;
                            }
                            reader.Close();

                            sharedData.LineCounts[sourceNode] = lineCount;

                            if (Options.Compiler.ObfuscateStrings)
                            {
                                HasStringConstExp checker = new HasStringConstExp();
                                start.Apply(checker);

                                if (!addedDeobfuscator /* && checker.HasStringConst*/)
                                {
                                    FileInfo dobfuscateFile = new FileInfo("Deobfuscator.LibraryData");
                                    IFormatter formatter = new BinaryFormatter();
                                    Stream stream = dobfuscateFile.Open(FileMode.Open);
                                    AASourceFile file = (AASourceFile) start.GetPSourceFile();

                                    AMethodDecl method = (AMethodDecl) formatter.Deserialize(stream);
                                    sharedData.DeobfuscateMethod = method;
                                    method.GetName().Line = 0;

                                    HasStringConstExp checker2 = new HasStringConstExp();
                                    method.Apply(checker2);
                                    file.GetDecl().Insert(0, method);
                                    stream.Close();

                                    addedDeobfuscator = true;

                                    foreach (AStringConstExp stringConstExp in checker2.List)
                                    {
                                        int line = -sharedData.UnobfuscatedStrings.Count - 1;
                                        AFieldDecl field = new AFieldDecl(new APublicVisibilityModifier(), null,
                                                                          new TConst("const", line, 0),
                                                                          new ANamedType(
                                                                              new TIdentifier("string", line, 1),
                                                                              null),
                                                                          new TIdentifier("Galaxy_pp_stringU" +
                                                                                          sharedData.UnobfuscatedStrings
                                                                                              .
                                                                                              Count),
                                                                          null);
                                        //If the strings are the same - point them to same field
                                        bool newField = true;
                                        foreach (
                                            AStringConstExp oldStringConstExp in sharedData.UnobfuscatedStrings.Keys)
                                        {
                                            if (stringConstExp.GetStringLiteral().Text ==
                                                oldStringConstExp.GetStringLiteral().Text)
                                            {
                                                field = sharedData.UnobfuscatedStrings[oldStringConstExp];
                                                newField = false;
                                                break;
                                            }
                                        }
                                        if (newField)
                                        {
                                            file.GetDecl().Insert(0, field);
                                            sharedData.ObfuscationFields.Add(field);
                                        }
                                        sharedData.UnobfuscatedStrings.Add(stringConstExp, field);

                                    }

                                }
                                foreach (AStringConstExp stringConstExp in checker.List)
                                {
                                    int line = -sharedData.ObfuscatedStrings.Count - 1;
                                    AFieldDecl field = new AFieldDecl(new APublicVisibilityModifier(), null,
                                                                      new TConst("const", line, 0),
                                                                      new ANamedType(new TIdentifier("string", line, 1),
                                                                                     null),
                                                                      new TIdentifier("Galaxy_pp_stringO" +
                                                                                      sharedData.ObfuscatedStrings.Count),
                                                                      null);
                                    //If the strings are the same - point them to same field
                                    bool newField = true;
                                    foreach (AStringConstExp oldStringConstExp in sharedData.ObfuscatedStrings.Keys)
                                    {
                                        if (stringConstExp.GetStringLiteral().Text ==
                                            oldStringConstExp.GetStringLiteral().Text)
                                        {
                                            field = sharedData.ObfuscatedStrings[oldStringConstExp];
                                            newField = false;
                                            break;
                                        }
                                    }
                                    if (newField)
                                    {
                                        AASourceFile file = (AASourceFile) sharedData.DeobfuscateMethod.Parent();
                                        file.GetDecl().Insert(file.GetDecl().IndexOf(sharedData.DeobfuscateMethod) + 1,
                                                              field);
                                        sharedData.ObfuscationFields.Add(field);
                                    }
                                    sharedData.ObfuscatedStrings.Add(stringConstExp, field);
                                }
                            }

                            sourceNode.SetName(new TIdentifier(filename));
                            root.GetSourceFiles().Add(start.GetPSourceFile());

                        }
                        catch (ParserException err)
                        {
                            String errMsg = err.Message;
                            //Remove [...]
                            errMsg = errMsg.Substring(errMsg.IndexOf(']') + 1).TrimStart();
                            errors.Add(new ErrorCollection.Error(err.Token, filename, errMsg));
                        }
                        reader.Close();
                    }
                }
               // Preprocessor.Parse(sources, errors);
                for (int i = 0; i < fileNames.Count; i++)
                {
                    string filename = fileNames[i];
                    StringReader reader = new StringReader(sources[i] ?? "");
                    Parser parser = new Parser(new Lexer(reader));
                    try
                    {
                        Start start = parser.Parse();
                        AASourceFile sourceNode = (AASourceFile)start.GetPSourceFile();
                        reader.Close();
                        reader.Dispose();
                        reader = new StringReader(sources[i] ?? "");
                        int lineCount = 0;
                        while (reader.ReadLine() != null)
                        {
                            lineCount++;
                        }
                        reader.Close();

                        sharedData.LineCounts[sourceNode] = lineCount;

                        //Extract encryption function
                         /*{
                             AASourceFile file = (AASourceFile) start.GetPSourceFile();
                             if (file.GetDecl().Count > 0 && file.GetDecl()[0] is AMethodDecl)
                             {
                                 AMethodDecl method = (AMethodDecl) file.GetDecl()[0];
                                 if (method.GetName().Text == "Galaxy_pp_Deobfuscate")
                                 {
                                     FileInfo dobfuscateFile = new FileInfo("Deobfuscator.LibraryData");
                                     IFormatter formatter = new BinaryFormatter();
                                     Stream stream = dobfuscateFile.Open(FileMode.Create);
                                     formatter.Serialize(stream, method);
                                     stream.Close();
                                 }
                             }
                         }*/

                        if (Options.Compiler.ObfuscateStrings)
                        {
                            HasStringConstExp checker = new HasStringConstExp();
                            start.Apply(checker);

                            if (!addedDeobfuscator /* && checker.HasStringConst*/)
                            {
                                FileInfo dobfuscateFile = new FileInfo("Deobfuscator.LibraryData");
                                IFormatter formatter = new BinaryFormatter();
                                Stream stream = dobfuscateFile.Open(FileMode.Open);
                                AASourceFile file = (AASourceFile)start.GetPSourceFile();

                                AMethodDecl method = (AMethodDecl)formatter.Deserialize(stream);
                                sharedData.DeobfuscateMethod = method;
                                method.GetName().Line = 0;

                                HasStringConstExp checker2 = new HasStringConstExp();
                                method.Apply(checker2);
                                file.GetDecl().Insert(0, method);
                                stream.Close();

                                addedDeobfuscator = true;

                                foreach (AStringConstExp stringConstExp in checker2.List)
                                {
                                    int line = -sharedData.UnobfuscatedStrings.Count - 1;
                                    AFieldDecl field = new AFieldDecl(new APublicVisibilityModifier(), null,
                                                                      new TConst("const", line, 0),
                                                                      new ANamedType(
                                                                          new TIdentifier("string", line, 1),
                                                                          null),
                                                                      new TIdentifier("Galaxy_pp_stringU" +
                                                                                      sharedData.UnobfuscatedStrings
                                                                                          .
                                                                                          Count),
                                                                      null);
                                    //If the strings are the same - point them to same field
                                    bool newField = true;
                                    foreach (
                                        AStringConstExp oldStringConstExp in sharedData.UnobfuscatedStrings.Keys)
                                    {
                                        if (stringConstExp.GetStringLiteral().Text ==
                                            oldStringConstExp.GetStringLiteral().Text)
                                        {
                                            field = sharedData.UnobfuscatedStrings[oldStringConstExp];
                                            newField = false;
                                            break;
                                        }
                                    }
                                    if (newField)
                                    {
                                        file.GetDecl().Insert(0, field);
                                        sharedData.ObfuscationFields.Add(field);
                                    }
                                    sharedData.UnobfuscatedStrings.Add(stringConstExp, field);

                                }

                            }
                            foreach (AStringConstExp stringConstExp in checker.List)
                            {
                                int line = -sharedData.ObfuscatedStrings.Count - 1;
                                AFieldDecl field = new AFieldDecl(new APublicVisibilityModifier(), null,
                                                                  new TConst("const", line, 0),
                                                                  new ANamedType(new TIdentifier("string", line, 1),
                                                                                 null),
                                                                  new TIdentifier("Galaxy_pp_stringO" +
                                                                                  sharedData.ObfuscatedStrings.Count),
                                                                  null);
                                //If the strings are the same - point them to same field
                                bool newField = true;
                                foreach (AStringConstExp oldStringConstExp in sharedData.ObfuscatedStrings.Keys)
                                {
                                    if (stringConstExp.GetStringLiteral().Text ==
                                        oldStringConstExp.GetStringLiteral().Text)
                                    {
                                        field = sharedData.ObfuscatedStrings[oldStringConstExp];
                                        newField = false;
                                        break;
                                    }
                                }
                                if (newField)
                                {
                                    AASourceFile file = (AASourceFile)sharedData.DeobfuscateMethod.Parent();
                                    file.GetDecl().Insert(file.GetDecl().IndexOf(sharedData.DeobfuscateMethod) + 1,
                                                          field);
                                    sharedData.ObfuscationFields.Add(field);
                                }
                                sharedData.ObfuscatedStrings.Add(stringConstExp, field);
                            }
                        }

                        sourceNode.SetName(new TIdentifier(filename));
                        root.GetSourceFiles().Add(start.GetPSourceFile());

                    }
                    catch (ParserException err)
                    {
                        String errMsg = err.Message;
                        //Remove [...]
                        errMsg = errMsg.Substring(errMsg.IndexOf(']') + 1).TrimStart();
                        errors.Add(new ErrorCollection.Error(err.Token, filename, errMsg));
                    }
                    reader.Close();
                }

                //Load libraries
                foreach (Library lib in ProjectProperties.CurrentProjectPropperties.Libraries)
                {
                    foreach (KeyValuePair<Library.File, string> sourceFile in lib.GetFiles())
                    {
                        StringReader sReader = new StringReader(sourceFile.Key.Text);
                        {
                            Parser parser = new Parser(new Lexer(sReader));

                            try
                            {
                                Start start = parser.Parse();
                                AASourceFile sourceNode = (AASourceFile) start.GetPSourceFile();
                                sReader.Close();
                                sReader.Dispose();
                                sReader = new StringReader(sourceFile.Key.Text);
                                int lineCount = 0;
                                while (sReader.ReadLine() != null)
                                {
                                    lineCount++;
                                }
                                sReader.Close();
                                sReader.Dispose();
                                sharedData.LineCounts[sourceNode] = lineCount;

                                if (Options.Compiler.ObfuscateStrings)
                                {
                                    HasStringConstExp checker = new HasStringConstExp();
                                    start.Apply(checker);

                                    if (!addedDeobfuscator /* && checker.HasStringConst*/)
                                    {
                                        FileInfo dobfuscateFile = new FileInfo("Deobfuscator.LibraryData");
                                        IFormatter formatter = new BinaryFormatter();
                                        Stream stream = dobfuscateFile.Open(FileMode.Open);
                                        AASourceFile file = (AASourceFile) start.GetPSourceFile();

                                        AMethodDecl method = (AMethodDecl) formatter.Deserialize(stream);
                                        sharedData.DeobfuscateMethod = method;
                                        method.GetName().Line = 0;

                                        HasStringConstExp checker2 = new HasStringConstExp();
                                        method.Apply(checker2);
                                        file.GetDecl().Insert(0, method);
                                        stream.Close();

                                        addedDeobfuscator = true;

                                        foreach (AStringConstExp stringConstExp in checker2.List)
                                        {
                                            int line = -sharedData.UnobfuscatedStrings.Count - 1;
                                            AFieldDecl field = new AFieldDecl(new APublicVisibilityModifier(), null,
                                                                              new TConst("const", line, 0),
                                                                              new ANamedType(
                                                                                  new TIdentifier("string", line, 1),
                                                                                  null),
                                                                              new TIdentifier("Galaxy_pp_stringU" +
                                                                                              sharedData.
                                                                                                  UnobfuscatedStrings
                                                                                                  .
                                                                                                  Count),
                                                                              null);
                                            //If the strings are the same - point them to same field
                                            bool newField = true;
                                            foreach (
                                                AStringConstExp oldStringConstExp in sharedData.UnobfuscatedStrings.Keys
                                                )
                                            {
                                                if (stringConstExp.GetStringLiteral().Text ==
                                                    oldStringConstExp.GetStringLiteral().Text)
                                                {
                                                    field = sharedData.UnobfuscatedStrings[oldStringConstExp];
                                                    newField = false;
                                                    break;
                                                }
                                            }
                                            if (newField)
                                            {
                                                file.GetDecl().Insert(0, field);
                                                sharedData.ObfuscationFields.Add(field);
                                            }
                                            sharedData.UnobfuscatedStrings.Add(stringConstExp, field);

                                        }

                                    }
                                    foreach (AStringConstExp stringConstExp in checker.List)
                                    {
                                        int line = -sharedData.ObfuscatedStrings.Count - 1;
                                        AFieldDecl field = new AFieldDecl(new APublicVisibilityModifier(), null,
                                                                          new TConst("const", line, 0),
                                                                          new ANamedType(
                                                                              new TIdentifier("string", line, 1),
                                                                              null),
                                                                          new TIdentifier("Galaxy_pp_stringO" +
                                                                                          sharedData.ObfuscatedStrings.
                                                                                              Count),
                                                                          null);
                                        //If the strings are the same - point them to same field
                                        bool newField = true;
                                        foreach (AStringConstExp oldStringConstExp in sharedData.ObfuscatedStrings.Keys)
                                        {
                                            if (stringConstExp.GetStringLiteral().Text ==
                                                oldStringConstExp.GetStringLiteral().Text)
                                            {
                                                field = sharedData.ObfuscatedStrings[oldStringConstExp];
                                                newField = false;
                                                break;
                                            }
                                        }
                                        if (newField)
                                        {
                                            AASourceFile file = (AASourceFile) sharedData.DeobfuscateMethod.Parent();
                                            file.GetDecl().Insert(
                                                file.GetDecl().IndexOf(sharedData.DeobfuscateMethod) + 1,
                                                field);
                                            sharedData.ObfuscationFields.Add(field);
                                        }
                                        sharedData.ObfuscatedStrings.Add(stringConstExp, field);
                                    }
                                }

                                sourceNode.SetName(new TIdentifier(sourceFile.Value));
                                root.GetSourceFiles().Add(start.GetPSourceFile());

                            }
                            catch (ParserException err)
                            {
                                String errMsg = err.Message;
                                //Remove [...]
                                errMsg = errMsg.Substring(errMsg.IndexOf(']') + 1).TrimStart();
                                errors.Add(new ErrorCollection.Error(err.Token, sourceFile.Value, errMsg));
                            }
                        }
                    }
                }

                string rootFileName = "";
                DirectoryInfo outputDir = ProjectDir.CreateSubdirectory("output");
                try
                {
                    if (!compilingFromCommandLine)
                        form.SetStatusText(LocRM.GetString("GC_Text4"));
                    sharedData.Libraries = libraryData;
                    Weeder.Parse(root, errors, sharedData);

                    if (!compilingFromCommandLine)
                        form.SetStatusText(LocRM.GetString("GC_Text5"));
                    if (!errors.HasErrors) EnviromentBuilding.Parse(root, errors, sharedData);

                    if (!compilingFromCommandLine)
                        form.SetStatusText(LocRM.GetString("GC_Text6"));
                    if (!errors.HasErrors) EnviromentChecking.Parse(root, errors, sharedData);

                    if (!compilingFromCommandLine)
                        form.SetStatusText(LocRM.GetString("GC_Text7"));
                    if (!errors.HasErrors) root.Apply(new LinkNamedTypes(errors, sharedData));

                    if (!compilingFromCommandLine)
                        form.SetStatusText(LocRM.GetString("GC_Text8"));
                    if (!errors.HasErrors) root.Apply(new FixGenerics(errors, sharedData));

                    if (!compilingFromCommandLine)
                        form.SetStatusText(LocRM.GetString("GC_Text9"));
                    if (!errors.HasErrors) root.Apply(new Enheritance(sharedData, errors));

                    if (!compilingFromCommandLine)
                        form.SetStatusText(LocRM.GetString("GC_Text10"));
                    if (!errors.HasErrors) TypeLinking.Parse(root, errors, sharedData);

                    if (!compilingFromCommandLine)
                        form.SetStatusText(LocRM.GetString("GC_Text11"));
                    if (!errors.HasErrors) TypeChecking.Parse(root, errors, sharedData);
                    if (!errors.HasErrors) root.Apply(new MakeEnrichmentLinks(sharedData, errors));
                    if (!errors.HasErrors) root.Apply(new SetArrayIndexes(sharedData, errors));
                    if (!compilingFromCommandLine)
                        form.SetStatusText(LocRM.GetString("GC_Text12"));
                    if (!errors.HasErrors) FinalTransformations.Parse(root, errors, sharedData, out rootFileName);
                    if (!compilingFromCommandLine)
                        form.SetStatusText(LocRM.GetString("GC_Text13"));
                    if (!errors.HasErrors) CodeGeneration.Parse(root, errors, sharedData, outputDir);
                    if (!errors.HasErrors) GenerateBankPreloadFile.Generate(sharedData, outputDir);
                }
                catch (ParserException err)
                {

                }

                Compiling = false;

                if (!errors.HasErrors)
                {
                    if (!compilingFromCommandLine)
                        form.SetStatusText(LocRM.GetString("GC_Text14"));
                    ProjectProperties.CurrentProjectPropperties.RootFileName = rootFileName;
                    ProjectProperties.CurrentProjectPropperties.CompileStatus =
                        ProjectProperties.ECompileStatus.SuccessfullyCompiled;
                    if (CompilationSuccessfull != null)
                        CompilationSuccessfull();
                }
                else
                {
                    if (!compilingFromCommandLine)
                        form.SetStatusText(LocRM.GetString("GC_Text15"));
                    if (CompilationFailed != null)
                        CompilationFailed();
                }

            }
            #if DEBUG
            finally
            {

            }
            #else
            catch (Exception error)
            {
                Compiling = false;
                //Program.ErrorHandeler(this, new ThreadExceptionEventArgs(error));
                new ExceptionForm(error, true).ShowDialog();
                form.SetStatusText("Critical compile error");
                if (CompilationFailed != null)
                    CompilationFailed();
            }
            #endif
        }
 private void errors_ErrorAdded(ErrorCollection sender, ErrorCollection.Error error)
 {
     if (form.messageView.InvokeRequired)
     {
         form.messageView.Invoke(new ErrorCollection.ErrorAddedEventHandler(errors_ErrorAdded), sender, error);
         return;
     }
     if (error.Warning)
     {
         if (!Options.General.ShowWarnings) return;
     }
     else
     {
         if (!Options.General.ShowErrors) return;
     }
     form.messageView.Nodes.Add(error);
 }