public static Category Deserialize(string xml)
        {
            XmlDocument xmlDocument = new XmlDocument();

            xmlDocument.LoadXml(xml);

            XmlElement rootElement = xmlDocument.DocumentElement;

            if (rootElement == null)
            {
                throw new ArgumentException("Xml structure is corrupted or incorrect");
            }

            var nodes = rootElement.ChildNodes;

            AssociativeTable <BaseElement, List <int> > table = new AssociativeTable <BaseElement, List <int> >();

            foreach (XmlElement node in nodes)
            {
                XmlElement  element        = (XmlElement)node.GetElementsByTagName("Element")[0];
                BaseElement baseElement    = BaseElement.Deserialize(element);
                List <int>  childIndexList = new List <int>();
                table.Add(baseElement, childIndexList);

                XmlNodeList relationXmlList = node.GetElementsByTagName("relation");

                foreach (XmlElement relationNode in relationXmlList)
                {
                    string attrVal       = relationNode.GetAttribute("index");
                    int    relativeIndex = Int32.Parse(attrVal);
                    childIndexList.Add(relativeIndex);
                }
            }

            // Restoring relation tree
            foreach (var pair in table)
            {
                BaseElement baseElement = pair.Val1;
                List <int>  relations   = pair.Val2;

                if (baseElement is Category category)
                {
                    foreach (var relationIndex in relations)
                    {
                        var relationPair = table[relationIndex];
                        category.Add(relationPair.Val1);
                    }
                }
            }

            return(table[0].Val1 as Category);
        }