/// <summary>
 /// Converts the <see cref="sourceValue" /> parameter to the <see cref="destinationType" /> parameter using <see cref="formatProvider"
 /// /> and <see cref="ignoreCase" />
 /// </summary>
 /// <param name="sourceValue">the <see cref="System.Object"/> to convert from</param>
 /// <param name="destinationType">the <see cref="System.Type" /> to convert to</param>
 /// <param name="formatProvider">not used by this TypeConverter.</param>
 /// <param name="ignoreCase">when set to <c>true</c>, will ignore the case when converting.</param>
 /// <returns>
 /// an instance of <see cref="GranularityType" />, or <c>null</c> if there is no suitable conversion.
 /// </returns>
 public override object ConvertFrom(object sourceValue, global::System.Type destinationType, global::System.IFormatProvider formatProvider, bool ignoreCase) => GranularityType.CreateFrom(sourceValue);
        //要使用递归么?

        /// <summary>
        /// 生成以指定CG为根的克隆家系
        /// </summary>
        /// <param name="crdFileName">克隆群所在版本的CRD文件名名称(不含路径)</param>
        /// <param name="cgInfo">克隆群信息(id及size)</param>
        /// <param name="mapXmlCollection">所用表示相邻版本版本映射的xml文档集合</param>
        public void BuildForCG(string crdFileName, CGInfo cgInfo, List <XmlDocument> mapXmlCollection, ref int id)
        {
            List <XmlDocument> mapXmlDocs = new List <XmlDocument>();

            #region 获得从crdFileName版本开始的所有映射文档,保存在mapXmlDocs中
            bool flag = false;
            foreach (XmlDocument mapXml in mapXmlCollection)
            {
                if (!flag)
                {
                    if (mapXml.DocumentElement.ChildNodes[0].InnerText == crdFileName)
                    {
                        mapXmlDocs.Add(mapXml);
                        flag = true;
                    }
                }
                else//将从这一版本开始的所有mapXml加入mapXmlDocs中
                {
                    mapXmlDocs.Add(mapXml);
                }
            }
            #endregion

            if (mapXmlDocs.Count == 0)
            {
                return;
            }
            else
            {
                #region 构造克隆家系信息
                string startFile = mapXmlDocs[0].DocumentElement.ChildNodes[0].InnerText;
                bool   atBlocks; //粒度标识,在函数调用时传递粒度信息
                if (startFile.IndexOf("_blocks-") != -1)
                {
                    CloneGenealogy.granularity = GranularityType.BLOCKS;
                    atBlocks          = true;
                    this.startVersion = startFile.Substring(0, startFile.IndexOf("_blocks-"));
                }
                else
                {
                    CloneGenealogy.granularity = GranularityType.FUNCTIONS;
                    atBlocks          = false;
                    this.startVersion = startFile.Substring(0, startFile.IndexOf("_functions-"));
                }
                this.rootCGid      = cgInfo.id; //保存根克隆群在该版本中的id
                this.evolutionList = new List <Evolution>();
                #endregion

                #region 构造进化关系列表
                int           index      = -1;
                int           evoID      = 0;
                int           endIndex   = -1;                  //记录克隆家系停止生长的版本的位置
                List <CGInfo> cgInfoList = new List <CGInfo>(); //cgInfoList用来存放当前所关注的克隆群,可能是多个,因此用列表
                cgInfoList.Add(cgInfo);
                foreach (XmlDocument mapXml in mapXmlDocs)
                {
                    index++;
                    List <CloneGroupMapping> cgMapList = new List <CloneGroupMapping>(); //存放当前两个版本间相关映射集
                    foreach (CGInfo info in cgInfoList)                                  //这个循环是考虑分裂的情况而设
                    {
                        //找出mapXml中以info代表的CG为源的所有映射,多数情况下为1个,少数情况多于一个
                        foreach (XmlElement cgMapNode in mapXml.DocumentElement.SelectNodes("CGMap"))
                        {
                            CloneGroupMapping cgMap = new CloneGroupMapping();
                            cgMap.CreateCGMapppingFromCGMapNode(cgMapNode);
                            if (cgMap.srcCGInfo.id == info.id)
                            {
                                cgMapList.Add(cgMap);
                            }
                        }
                    }
                    string srcFileName  = mapXml.DocumentElement.ChildNodes[0].InnerText;
                    string destFileName = mapXml.DocumentElement.ChildNodes[1].InnerText;
                    cgInfoList = new List <CGInfo>();
                    if (cgMapList.Count != 0)
                    {
                        //为选出的每一个CGMap构造Evolution对象。同时更新cgInfoList
                        foreach (CloneGroupMapping cgMap in cgMapList)
                        {
                            Evolution evolution = new Evolution();
                            evolution.BuildFromCGMap(cgMap, srcFileName, destFileName, ref this.evolutionList, ref evoID, atBlocks);
                            this.evolutionList.Add(evolution);
                            cgInfoList.Add(cgMap.destCGInfo);
                            endIndex = index;   //更新endIndex的值
                        }
                    }
                    else//当cgMapList.Count为0时,说明此克隆家系停止生长
                    {
                        break;
                    }
                }
                #endregion

                #region 补全克隆家系信息
                this.age = endIndex + 2; //计算年龄(年龄指克隆群在几个版本中存在,等于它所发生的进化次数+1)
                if (this.age > 1)        //如果该克隆群寿命大于1(即不是只在单个版本出现)
                {
                    string endFile = mapXmlDocs[endIndex].DocumentElement.ChildNodes[1].InnerText;
                    if (atBlocks)
                    {
                        this.endVersion = endFile.Substring(0, endFile.IndexOf("_blocks-"));
                    }
                    else
                    {
                        this.endVersion = endFile.Substring(0, endFile.IndexOf("_functions-"));
                    }

                    if (this.evolutionList != null && this.evolutionList.Count != 0)
                    {
                        id++;
                        this.ID = id.ToString();
                    }

                    #region 统计各种进化模式出现的次数,保存在evoPatternCount数组中
                    this.evoPatternCount = new int[7] {
                        0, 0, 0, 0, 0, 0, 0
                    };
                    foreach (Evolution evolution in this.evolutionList)
                    {
                        if (evolution.CGMapInfo.pattern.IndexOf("STATIC") != -1)
                        {
                            this.evoPatternCount[0]++;
                        }
                        if (evolution.CGMapInfo.pattern.IndexOf("SAME") != -1)
                        {
                            this.evoPatternCount[1]++;
                        }
                        if (evolution.CGMapInfo.pattern.IndexOf("ADD") != -1)
                        {
                            this.evoPatternCount[2]++;
                        }
                        if (evolution.CGMapInfo.pattern.IndexOf("DELETE") != -1)
                        {
                            this.evoPatternCount[3]++;
                        }
                        if (evolution.CGMapInfo.pattern.IndexOf("CONSISTENTCHANGE") != -1)
                        {
                            this.evoPatternCount[4]++;
                        }
                        if (evolution.CGMapInfo.pattern.IndexOf("INCONSISTENTCHANGE") != -1)
                        {
                            this.evoPatternCount[5]++;
                        }
                        if (evolution.CGMapInfo.pattern.IndexOf("SPLIT") != -1)
                        {
                            this.evoPatternCount[6]++;
                        }
                    }
                    #endregion
                }

                #endregion
            }
        }