private void Parse(List <Line> xml_lines)
        {
            List <Text>  texts        = new List <Text>();
            List <Tag>   startingTags = new List <Tag>();
            List <Tag>   endingTags   = new List <Tag>();
            List <Error> errorsList   = new List <Error>();
            List <Tag>   allTags      = new List <Tag>();

            bool HasXmlDec = false;
            int  level     = 0;
            int  tag_id    = 1;

            var xmlFile = new Xml()
            {
                HasError   = false,
                HasRoot    = false,
                LineNumber = xml_lines.Count()
            };

            // walidujemy poprawność każdej linijki.
            foreach (var line in xml_lines)
            {
                bool startingTagDec = false;
                bool endingTagDec   = false;
                bool otherDec       = false;
                bool textDec        = false;
                bool xmlDec         = false;


                string tempTag    = "";
                int    lineNumber = line.LineNumber;
                //bool hasError = line.HasError;

                var characters       = line.Content;
                var charactersNumber = line.Content.Length;
                for (int i = 0; i < charactersNumber; i++)
                {
                    if (characters[i] == '<')
                    { // start
                        otherDec = true;
                        if (characters[i + 1] == '?')
                        { // początek deklaracji Xml
                            if (CheckXml(line.Content))
                            {
                                HasXmlDec = true;
                            }
                            else
                            {
                                HasXmlDec = false;
                            }
                        }
                        else if (characters[i + 1] == '/')
                        {                        // początek tagu zamykającego
                            endingTagDec = true; // zmienna pomocnicza
                            level--;
                            Tag endTag = GetTag(line.Content, i + 2, line.LineNumber);

                            // musimy ustalic temu tagowi jeszcze rodzica
                            var parent_tag = startingTags.Where(t => t.TagId < tag_id && t.ChildLevel == level - 1).OrderByDescending(t => t.TagId).FirstOrDefault();
                            if (parent_tag == null)
                            {
                                endTag.Parent  = null;
                                endTag.TagType = true;
                            }
                            else
                            {
                                endTag.Parent = parent_tag;
                            }

                            endTag.ChildLevel = level;
                            endTag.TagId      = tag_id;
                            tag_id++;

                            // przy każdym tagu kończącym obniżamy poziom o 1;
                            endingTags.Add(endTag);
                            allTags.Add(endTag);
                            //Console.Write("END:"+endTagName);
                        }
                        else if (characters[i + 1] == ' ')
                        {
                            errors_list.Add(new Error()
                            {
                                ErrorName = "Bad tag declaration", ErrorValue = "Tag declarations cannot contain spaces", Warning = false, LineNumber = lineNumber
                            });
                        }
                        else if (Char.IsDigit(characters[i + 1]))
                        {
                            errors_list.Add(new Error()
                            {
                                LineNumber = lineNumber, ErrorName = "Tag error", ErrorValue = "Tag's name cannot start with digit", Warning = false
                            });
                        }
                        else
                        {
                            // pierwszy znak to < następny to tekst.
                            // mamy więc do czynienia z tagiem początkowym
                            // pobieramy jego dane i tyle.
                            startingTagDec = true; // zmienna pomocnicza;

                            Tag startTag = GetTag(line.Content, i + 1, line.LineNumber);
                            startTag.ChildLevel = level;
                            startTag.TagId      = tag_id;

                            // musimy ustalic temu tagowi jeszcze rodzica
                            var parent_tag = startingTags.Where(t => t.TagId < tag_id && t.ChildLevel == level - 1).OrderByDescending(t => t.TagId).FirstOrDefault();
                            if (parent_tag == null)
                            {
                                startTag.Parent  = null;
                                startTag.TagType = true;
                            }
                            else
                            {
                                startTag.Parent = parent_tag;
                            }

                            tag_id++;
                            level++; // przy każdym tagu otwierającym podbijamy poziom o 1
                            startingTags.Add(startTag);
                            allTags.Add(startTag);
                            //Console.WriteLine("START:"+startTagName);
                        }
                    }
                    else if (characters[i] == '>')
                    { // koniec
                        // czyścimy zmienne pomocnicze
                        startingTagDec = false;
                        xmlDec         = false;
                        otherDec       = false;
                        endingTagDec   = false;
                    }
                    else if (regexLettersNumbers.IsMatch(characters[i].ToString()) && startingTagDec == false && endingTagDec == false && xmlDec == false && otherDec == false)
                    { // chyba tutaj już rozpatrujemy zwykły tekst
                        if (!regexAll.IsMatch(characters[i - 1].ToString()))
                        {
                            string value = GetTextValue(line.Content, i);
                            //Console.WriteLine("TEKST: " + line.Content +  " :TEKST");
                            texts.Add(new Text()
                            {
                                TextId = 1,
                                Value  = value
                            });
                            //Console.WriteLine("TE:" + value + "CC");
                        }
                    }
                }
            }
            if (HasXmlDec == true)
            {
                xmlFile.HasXmlDec = true;
            }
            else
            {
                xmlFile.HasXmlDec = false;
            }

            xmlFile.EndingTagsList     = endingTags;
            xmlFile.StartingTagsList   = startingTags;
            xmlFile.StartingTagsNumber = startingTags.Count();
            xmlFile.EndingTagsNumber   = endingTags.Count();
            xmlFile.AllTags            = allTags;

            main_xml_file = xmlFile;
        }
        private void Validate(Xml xmlfile)
        {
            //check XML declaration
            if (xmlfile.HasXmlDec == false)
            {
                errors_list.Add(new Error()
                {
                    LineNumber = 0, ErrorName = "XML declaration", ErrorValue = "No xml declaration found in the document.", Warning = true
                });
            }

            // check if root element exists
            if (xmlfile.StartingTagsList.First().TagName != xmlfile.EndingTagsList.Last().TagName)
            {
                if (xmlfile.HasXmlDec == true)
                {
                    errors_list.Add(new Error()
                    {
                        LineNumber = 1, ErrorName = "Root element error", ErrorValue = "No root element declaration", Warning = false
                    });
                }
                else
                {
                    errors_list.Add(new Error()
                    {
                        LineNumber = 0, ErrorName = "Root element error", ErrorValue = "No root element declaration", Warning = false
                    });
                }
            }

            // starting tags vs ending tags
            foreach (var tag in xmlfile.StartingTagsList)
            {
                if (tag.TagType == true)
                { // tag type TRUE oznacza root'a
                    if (xmlfile.EndingTagsList.Where(t => t.TagName == tag.TagName).FirstOrDefault() == null)
                    {
                        errors_list.Add(new Error()
                        {
                            LineNumber = tag.LineNumber, ErrorName = "Tag error", ErrorValue = "Cannot find ending tag for already decalred starting tag (" + tag.TagName + ")", Warning = false
                        });
                    }
                }
                else
                {
                    if (xmlfile.EndingTagsList.Where(t => t.TagName == tag.TagName && t.ChildLevel == tag.ChildLevel && t.Parent == tag.Parent).FirstOrDefault() == null)
                    {
                        if (!this.CheckNested(tag))
                        {
                            if (xmlfile.EndingTagsList.Where(t => t.TagName.ToLower() == tag.TagName.ToLower() && t.ChildLevel == tag.ChildLevel && t.Parent == tag.Parent).FirstOrDefault() == null)
                            {
                                errors_list.Add(new Error()
                                {
                                    LineNumber = tag.LineNumber, ErrorName = "Tag error", ErrorValue = "Cannot find ending tag for already decalred starting tag (" + tag.TagName + ")", Warning = false
                                });
                            }
                            else
                            {
                                errors_list.Add(new Error()
                                {
                                    LineNumber = tag.LineNumber, ErrorName = "Tag declaration error", ErrorValue = "Case sensitive error. (" + tag.TagName + ")", Warning = false
                                });
                            }
                        }
                    }
                }
            }

            // check tags names - cannot start with number and "XML" word
            foreach (var tag in xmlfile.StartingTagsList)
            {
                if (regexTagNameFirstDigit.IsMatch(tag.TagName))
                {
                    errors_list.Add(new Error()
                    {
                        LineNumber = tag.LineNumber, ErrorName = "Tag error", ErrorValue = "Tag's name cannot start with digit (" + tag.TagName + ")", Warning = false
                    });
                }
                if (regexTagName.IsMatch(tag.TagName))
                {
                    errors_list.Add(new Error()
                    {
                        LineNumber = tag.LineNumber, ErrorName = "Tag error", ErrorValue = "Tag's name cannot start with XML word (" + tag.TagName + ")", Warning = false
                    });
                }
            }

            Console.WriteLine(String.Join("\n", xmlfile.StartingTagsList.Select(a => a.TagName + ":" + a.ChildLevel + ":" + (a.Parent != null ? a.Parent.TagName : "BRAK"))));
            Console.WriteLine("\n KON \n" + String.Join("\n", xmlfile.EndingTagsList.Select(a => a.TagName + ":" + a.ChildLevel + ":" + (a.Parent != null ? a.Parent.TagName : "BRAK"))));

            this.PrintErrors();
        }