public MultipleGraphics(ResultResearch r)
        {
            InitializeComponent();

            this.research = r;

            SortedDictionary<double, SortedDictionary<double, SubGraphsInfo>>.KeyCollection keys =
                this.research.Result.Keys;
            foreach (double k in keys)
            {
                Chart graphic = new Chart();
                graphic.Titles.Add("Network Size = " + this.research.Size.ToString());

                ChartArea chArea = new ChartArea("Current Level = " + k.ToString());
                chArea.AxisX.Title = "Mu";
                chArea.AxisY.Title = "Order";
                graphic.ChartAreas.Add(chArea);

                Series s = new Series("Current Level = " + k.ToString());
                s.ChartType = SeriesChartType.Line;
                s.Color = Color.Red;
                foreach (KeyValuePair<double, SubGraphsInfo> v in this.research.Result[k])
                {
                    s.Points.Add(new DataPoint(v.Key, v.Value.avgOrder));
                }
                graphic.Series.Add(s);

                graphic.Dock = DockStyle.Fill;
                TabPage page = new TabPage("Current Level = " + k.ToString());
                page.Controls.Add(graphic);
                this.graphicsTab.TabPages.Add(page);

                this.graphics.Add(graphic);
            }
        }
        private void researchNamesCmb_SelectedValueChanged(object sender, EventArgs e)
        {
            this.currentResearch =
                storage.LoadResearch(this.researchesID[this.researchNamesCmb.SelectedIndex]);

            this.informationGrd.Rows.Clear();

            this.informationGrd.Rows.Add("ID", this.currentResearch.ResearchID.ToString());
            this.informationGrd.Rows.Add("Name", this.currentResearch.Name);
            this.informationGrd.Rows.Add("Delta", this.currentResearch.Delta.ToString());
            this.informationGrd.Rows.Add("Realization Count", this.currentResearch.RealizationCount);
            this.informationGrd.Rows.Add("Function", this.currentResearch.Function);
            this.informationGrd.Rows.Add("Size", this.currentResearch.Size);
            foreach (GenerationParam p in this.currentResearch.GenerationParams.Keys)
            {
                this.informationGrd.Rows.Add(p.ToString(),
                    this.currentResearch.GenerationParams[p].ToString());
            }
        }
 // Удаление исследования по данному идентификатору исследования.
 public override void DeleteResearch(ResultResearch research)
 {
     throw new NotImplementedException();
 }
        // Сохранение исследования в xml файле.
        public override void SaveResearch(ResultResearch research)
        {
            using (XmlTextWriter writer = new XmlTextWriter(
                this.directory + research.ResearchID.ToString() + ".xml",
                Encoding.ASCII))
            {
                // Сохранение общей информации для данной сборки.
                log.Info("Saving common info of research.");

                writer.Formatting = Formatting.Indented;
                writer.WriteStartDocument(true);
                writer.WriteStartElement("research");

                writer.WriteElementString("id", research.ResearchID.ToString());
                writer.WriteElementString("name", research.Name);
                writer.WriteElementString("date", DateTime.Now.ToString());
                writer.WriteElementString("realizationcount", research.RealizationCount.ToString());
                writer.WriteElementString("delta", research.Delta.ToString());
                writer.WriteElementString("function", research.Function);
                writer.WriteElementString("size", research.Size.ToString());

                writer.WriteStartElement("graphmodel");
                writer.WriteAttributeString("id", GetModelID(research.ModelType).ToString());
                writer.WriteAttributeString("modelname", research.ModelType.Name);
                writer.WriteEndElement();

                // Сохранение значений параметров генерации для данной сборки.
                log.Info("Saving generation parameters values of research.");

                writer.WriteStartElement("generationparams");
                if (research.GenerationParams != null)
                {
                    foreach (GenerationParam genParameter in research.GenerationParams.Keys)
                    {
                        writer.WriteStartElement("generationparam");
                        writer.WriteAttributeString("id", Convert.ToInt32(genParameter).ToString());
                        writer.WriteAttributeString("parametername", Enum.GetName(typeof(GenerationParam), genParameter));
                        writer.WriteAttributeString("value", research.GenerationParams[genParameter].ToString());
                        writer.WriteEndElement();
                    }
                }
                writer.WriteEndElement();   // generationparams

                // Сохранение результатов анализа для данной сборки.
                log.Info("Saving research results.");

                writer.WriteStartElement("results");
                foreach (double l in research.Result.Keys)
                {
                    log.Info("Saving analyze results for level - " + l.ToString() + ".");

                    writer.WriteStartElement("level" + l.ToString());
                    SortedDictionary<double, SubGraphsInfo> r = research.Result[l];
                    foreach (double degree in r.Keys)
                    {
                        writer.WriteStartElement("avgorder");
                        writer.WriteAttributeString("q", degree.ToString());
                        writer.WriteAttributeString("order", r[degree].avgOrder.ToString());
                        writer.WriteAttributeString("count", r[degree].avgOrderCount.ToString());

                        writer.WriteStartElement("secondmax");
                        writer.WriteAttributeString("value", r[degree].secondMax.ToString());
                        writer.WriteAttributeString("count", r[degree].secondMaxCount.ToString());
                        writer.WriteEndElement();

                        writer.WriteElementString("avgorderrest", r[degree].avgOrderRest.ToString());
                        writer.WriteEndElement();
                    }
                    writer.WriteEndElement();   // level
                }

                writer.WriteEndElement();   // results
                writer.WriteEndElement();   // research
            }
        }
        public override List<ResultResearch> LoadAllResearches()
        {
            List<ResultResearch> research = new List<ResultResearch>();
            ResultResearch r = null;

            foreach (string file in Directory.GetFiles(directory, "*.xml",
                SearchOption.TopDirectoryOnly))
            {
                r = new ResultResearch();
                research.Add(r);
                using (XmlTextReader reader = new XmlTextReader(file))
                {
                    try
                    {
                        reader.WhitespaceHandling = WhitespaceHandling.None;
                        while (reader.Read())
                        {

                            if (reader.NodeType == XmlNodeType.Element)
                            {
                                if (reader.Name == "id")
                                {
                                    r.ResearchID = new Guid(reader.ReadElementString());
                                }
                                if (reader.Name == "name")
                                {
                                    r.Name = reader.ReadElementString();
                                }
                                // !исправить!
                            }
                        }
                    }
                    catch (SystemException)
                    {
                        continue;
                    }
                }
            }

            return research;
        }
        // Загрузка исследования по данному идентификатору исследования.
        public override ResultResearch LoadResearch(Guid researchID)
        {
            log.Info("Loading research with ID " + researchID.ToString() + ".");

            log.Info("Loading common info of research.");

            ResultResearch resultResearch = new ResultResearch();
            resultResearch.ResearchID = researchID;

            XmlDocument xml = new XmlDocument();

            xml.Load(this.directory + researchID.ToString() + ".xml");
            resultResearch.Name = xml.SelectSingleNode("/research/name").InnerText;
            resultResearch.Delta = Double.Parse(xml.SelectSingleNode("/research/delta").InnerText);
            resultResearch.RealizationCount = Int32.Parse(xml.SelectSingleNode("/research/realizationcount").InnerText);
            resultResearch.Function = xml.SelectSingleNode("/research/function").InnerText;
            resultResearch.ModelType = GetModelType(int.Parse(xml.SelectSingleNode("/research/graphmodel").Attributes["id"].Value));
            resultResearch.Size = Int32.Parse(xml.SelectSingleNode("/research/size").InnerText);

            log.Info("Loading generation parameters values of research.");
            foreach (XmlNode paramNode in xml.SelectNodes("/research/generationparams/generationparam"))
            {
                GenerationParam param = (GenerationParam)Enum.ToObject(typeof(GenerationParam), int.Parse(paramNode.Attributes["id"].Value));

                GenerationParamInfo paramInfo = (GenerationParamInfo)(param.GetType().GetField(param.ToString()).GetCustomAttributes(typeof(GenerationParamInfo), false)[0]);
                if (paramInfo.Type.Equals(typeof(Double)))
                {
                    resultResearch.GenerationParams.Add(param, Convert.ToDouble(paramNode.Attributes["value"].Value, CultureInfo.InvariantCulture));
                }
                else if (paramInfo.Type.Equals(typeof(Int16)))
                {
                    resultResearch.GenerationParams.Add(param, Convert.ToInt16(paramNode.Attributes["value"].Value));
                }
                else if (paramInfo.Type.Equals(typeof(Int32)))
                {
                    resultResearch.GenerationParams.Add(param, Convert.ToInt32(paramNode.Attributes["value"].Value));
                }
                else if (paramInfo.Type.Equals(typeof(bool)))
                {
                    resultResearch.GenerationParams.Add(param, Convert.ToBoolean(paramNode.Attributes["value"].Value));
                }
                else if (paramInfo.Type.Equals(typeof(String)))
                {
                    resultResearch.GenerationParams.Add(param, Convert.ToString(paramNode.Attributes["value"].Value));
                }
            }

            log.Info("Loading research results.");

            int count = xml.SelectSingleNode("/research/results").ChildNodes.Count;
            for (int i = 1; i <= count; ++i)
            {
                SortedDictionary<double, SubGraphsInfo> r = new SortedDictionary<double, SubGraphsInfo>();
                foreach (XmlNode paramNode in xml.SelectNodes("/research/results/level" + i.ToString()))
                {
                    foreach (XmlNode item in paramNode.SelectNodes("avgorder"))
                    {
                        SubGraphsInfo tempInfo = new SubGraphsInfo();
                        tempInfo.avgOrder = Double.Parse(item.Attributes["order"].Value);
                        tempInfo.avgOrderCount = Double.Parse(item.Attributes["count"].Value);

                        // read <secondmax> value;
                        tempInfo.secondMax = Double.Parse(item.ChildNodes[0].Attributes["value"].InnerText);
                        tempInfo.secondMaxCount = Double.Parse(item.ChildNodes[0].Attributes["count"].Value);

                        // read <avgorderrest> value
                        tempInfo.avgOrderRest = Double.Parse(item.ChildNodes[1].InnerText);

                        r.Add(Double.Parse(item.Attributes["q"].Value), tempInfo);
                    }
                }

                resultResearch.Result.Add(i, r);
            }

            return resultResearch;
        }
 // Абстрактный метод для удаления исследования из хранилище данных по данному идентификатору
 // исследования.
 public abstract void DeleteResearch(ResultResearch research);
 // Абстрактный метод для сохранения результатов исследования в хранилище данных.
 public abstract void SaveResearch(ResultResearch research);
        private void startHierarchic_Click(object sender, EventArgs e)
        {
            ResultResearch result = new ResultResearch();
            result.Name = this.jobName;
            result.ModelType = typeof(HierarchicModel);
            result.Delta = Double.Parse(this.deltaExtendedTxt.Text);
            result.RealizationCount = (Int32)this.realizationCountNum.Value;
            result.Function = this.probabilityFunctionCmb.Text;
            result.GenerationParams[GenerationParam.BranchIndex] = Int16.Parse(this.branchIndexCmb.Text);
            result.GenerationParams[GenerationParam.Level] = Int16.Parse(this.maxLevelCmb.Text);
            result.Size = (int)Math.Pow(Int16.Parse(this.branchIndexCmb.Text), Int16.Parse(this.maxLevelCmb.Text));

            Int16 maxLevel = Int16.Parse(this.maxLevelCmb.Text);
            for (Int16 g = 1; g <= maxLevel; ++g)
            {
                result.Result.Add(g, new SortedDictionary<double, SubGraphsInfo>());
            }

            double muLow = Double.Parse(this.muRangeLowExtendedTxt.Text);
            double muHigh = Double.Parse(this.muRangeHighExtendedTxt.Text);
            double muDelta = Double.Parse(this.deltaExtendedTxt.Text);

            double muTemp = muLow;
            SubGraphsInfo tempInfo = new SubGraphsInfo();
            while (muTemp < muHigh)
            {
                SortedDictionary<double, SubGraphsInfo> r = AnalyzeHierarchic(muTemp);
                foreach (double gamma in r.Keys)
                {
                    result.Result[gamma].Add(muTemp, r[gamma]);
                }

                muTemp += muDelta;
            }

            XMLResultStorage storage = new XMLResultStorage(Options.StorageDirectory);
            storage.SaveResearch(result);

            MessageBox.Show("Results are saved succesfully!");
        }
        private void startGlobal_Click(object sender, EventArgs e)
        {
            Int16 p = Int16.Parse(this.branchIndexCmb.Text);
            Int16 maxLevel = Int16.Parse(this.maxLevelCmb.Text);
            int realizationCount = (Int32)this.realizationCountNum.Value;
            double muLow = Double.Parse(this.muRangeLowExtendedTxt.Text);
            double muHigh = Double.Parse(this.muRangeHighExtendedTxt.Text);
            double muDelta = Double.Parse(this.deltaExtendedTxt.Text);

            ResultResearch result = new ResultResearch();
            result.Name = this.jobName;
            result.ModelType = typeof(HierarchicModel);
            result.Delta = muDelta;
            result.RealizationCount = realizationCount;
            result.Function = this.probabilityFunctionCmb.Text;
            result.GenerationParams[GenerationParam.BranchIndex] = p;
            result.GenerationParams[GenerationParam.Level] = maxLevel;
            result.Size = (int)Math.Pow(p, maxLevel);
            result.Result.Add(maxLevel, new SortedDictionary<double, SubGraphsInfo>());

            Dictionary<GenerationParam, object> genParameters = new Dictionary<GenerationParam, object>();
            genParameters.Add(GenerationParam.BranchIndex, p);
            genParameters.Add(GenerationParam.Level, maxLevel);

            HierarchicGenerator hGenerator = new HierarchicGenerator();
            HierarchicAnalyzer hAnalyzer;

            double muTemp = muLow;

            SortedDictionary<int, int> subGraphInfo = new SortedDictionary<int,int>();
            while (muTemp <= muHigh)
            {
                SubGraphsInfo tempInfo = new SubGraphsInfo();
                for (int r = 0; r < realizationCount; ++r)
                {
                    genParameters[GenerationParam.Mu] = muTemp;
                    hGenerator.Generation(genParameters);
                    hAnalyzer = new HierarchicAnalyzer((HierarchicContainer)hGenerator.Container);
                    subGraphInfo = hAnalyzer.GetConnSubGraph();

                    tempInfo.avgOrder += subGraphInfo.Last().Key;
                    tempInfo.avgOrderCount += subGraphInfo.Last().Value;

                    if (subGraphInfo.Count > 1)
                    {
                        subGraphInfo.Remove(subGraphInfo.Last().Key);
                        tempInfo.secondMax += subGraphInfo.Last().Key;
                        tempInfo.secondMaxCount += subGraphInfo.Last().Value;
                    }

                    if (subGraphInfo.Count > 2)
                    {
                        subGraphInfo.Remove(subGraphInfo.Last().Key);
                        tempInfo.avgOrderRest += subGraphInfo.Average(x => x.Key);
                    }
                }
                tempInfo.avgOrder /= (double)realizationCount;
                tempInfo.avgOrder /= result.Size;
                tempInfo.avgOrderCount /= (double)realizationCount;

                tempInfo.secondMax /= (double)realizationCount;
                tempInfo.secondMax /= result.Size;
                tempInfo.secondMaxCount /= (double)realizationCount;

                tempInfo.avgOrderRest /= (double)realizationCount;
                tempInfo.avgOrderRest /= result.Size;

                result.Result[maxLevel].Add(muTemp, tempInfo);

                muTemp += muDelta;
            }

            XMLResultStorage storage = new XMLResultStorage(Options.StorageDirectory);
            storage.SaveResearch(result);

            MessageBox.Show("Results are saved succesfully!");
        }
        /*private void startExtended_Click(object sender, EventArgs e)
        {
            ResultResearch result = new ResultResearch();
            result.Name = this.jobName;
            result.ModelType = typeof(HierarchicModel);
            result.Delta = Double.Parse(this.deltaExtendedTxt.Text);
            result.RealizationCount = (Int32)this.realizationCountNum.Value;
            result.Function = this.probabilityFunctionCmb.Text;
            result.GenerationParams[GenerationParam.BranchIndex] = Int16.Parse(this.branchIndexCmb.Text);
            result.GenerationParams[GenerationParam.Level] = Int16.Parse(this.maxLevelCmb.Text);
            result.Size = (int)Math.Pow(Int16.Parse(this.branchIndexCmb.Text), Int16.Parse(this.maxLevelCmb.Text));

            Int16 maxLevel = Int16.Parse(this.maxLevelCmb.Text);
            for (Int16 g = 1; g <= maxLevel; ++g)
            {
                result.Result.Add(g, AnalyzeExtendedHierarchic(g));
            }

            XMLResultStorage storage = new XMLResultStorage(Options.StorageDirectory);
            storage.SaveResearch(result);

            MessageBox.Show("Results are saved succesfully!");
        }*/
        private void startER_Click(object sender, EventArgs e)
        {
            ResultResearch result = new ResultResearch();
            result.Name = this.jobName;
            result.ModelType = typeof(ERModel);

            // TODO remove hardcoded data
            result.Delta = 0.00001;
            result.RealizationCount = 100;
            result.GenerationParams[GenerationParam.Vertices] = 65536;
            SortedDictionary<double, SubGraphsInfo> pInfo =
                new SortedDictionary<double, SubGraphsInfo>();

            this.folderBrowserDialog1.ShowDialog();
            string dirName = this.folderBrowserDialog1.SelectedPath;

            DirectoryInfo parentDir = new DirectoryInfo(dirName);
            foreach (FileInfo f in parentDir.GetFiles())
            {
                double p = Double.Parse(f.Name.Remove(f.Name.Length - 4));
                SubGraphsInfo value = new SubGraphsInfo();

                SortedDictionary<int, double> r = new SortedDictionary<int, double>();
                using (StreamReader streamReader = new StreamReader(f.FullName, System.Text.Encoding.Default))
                {
                    string contents;

                    while ((contents = streamReader.ReadLine()) != null)
                    {
                        string first = "", second = "";
                        int j = 0;
                        while (contents[j] != ' ')
                        {
                            first += contents[j];
                            ++j;
                        }

                        second = contents.Substring(j);

                        r.Add(int.Parse(first), double.Parse(second));
                    }
                }

                value.avgOrder = r.First().Value;
                value.avgOrderCount = r.First().Key;

                if (r.Count > 1)
                {
                    r.Remove(r.First().Key);
                    value.secondMax = r.First().Value;
                    value.secondMaxCount = r.First().Key;
                }

                if (r.Count > 2)
                {
                    r.Remove(r.First().Key);
                    value.avgOrderRest = r.Average(x => x.Value);
                }

                pInfo.Add(p, value);
            }

            result.Result.Add(1, pInfo);

            XMLResultStorage storage = new XMLResultStorage(Options.StorageDirectory);
            storage.SaveResearch(result);

            MessageBox.Show("Results are saved succesfully!");
        }