static UniHanData()
        {
            var settings = Properties.Settings.Default;

            Sources = new MultiDict<int, string>();
            Mappings = new MultiDict<int, string>();
            Variants = new MultiDict<int, int>();

            var path = Path.Combine(Path.GetDirectoryName(typeof(UniHanData).Assembly.Location), settings.UnicodeZipFilename);
            using (var zip = ZipFile.OpenRead(path))
            {
                using (var rd = new FieldReader(zip.GetEntry(settings.Unihan_IRGSources).Open(), '\t'))
                {
                    string[] fields;
                    while ((fields = rd.Read()) != null)
                    {
                        if (fields[1].StartsWith("kIRG_") && fields[1].EndsWith("Source"))
                        {
                            var code = int.Parse(fields[0].Substring(2), NumberStyles.HexNumber);
                            Sources.Add(code, fields[2]);
                        }
                        else if (fields[1].EndsWith("Variant"))
                        {
                            var code = int.Parse(fields[0].Substring(2), NumberStyles.HexNumber);
                            var vant = int.Parse(fields[2].Substring(2), NumberStyles.HexNumber);
                            Variants.Add(code, vant);
                        }
                    }
                }

                using (var rd = new FieldReader(zip.GetEntry(settings.Unihon_OtherMappings).Open(), '\t'))
                {
                    string[] fields;
                    while ((fields = rd.Read()) != null)
                    {
                        var code = int.Parse(fields[0].Substring(2), NumberStyles.HexNumber);
                        var mapping = fields[1].Substring(1) + "-" + fields[2].Replace(',', '-').Replace(':','-');
                        Mappings.Add(code, mapping);
                    }
                }

                using (var rd = new FieldReader(zip.GetEntry(settings.Unihan_Variants).Open(), '\t'))
                {
                    string[] fields;
                    while ((fields = rd.Read()) != null)
                    {
                        var code = int.Parse(fields[0].Substring(2), NumberStyles.HexNumber);
                        foreach (var v in fields[2].Split('\t', ' ', '<').Where(s => s.StartsWith("U+")))
                        {
                            var vant = int.Parse(v.Substring(2), NumberStyles.HexNumber);
                            Variants.Add(code, vant);
                        }
                    }
                }
            }
        }
        static OtherData()
        {
            var settings = Properties.Settings.Default;

            var classes = new MultiDict<int, string>();
            var reuser = new ObjectReuser<string>();

            var path = Path.Combine(Path.GetDirectoryName(typeof(OtherData).Assembly.Location), settings.UnicodeZipFilename);
            using (var zip = ZipFile.OpenRead(path))
            {
                using (var rd = new FieldReader(zip.GetEntry(settings.OtherAttribution).Open(), ';'))
                {
                    string[] fields;
                    while ((fields = rd.Read()) != null)
                    {
                        classes.Add(int.Parse(fields[0], System.Globalization.NumberStyles.HexNumber), reuser.Get(fields[1].Trim()));
                    }
                }
            }

            Classes = classes;
        }
        private static void ProcessMethods(AssemblyDataItem asmDataItem, ICollection<AssemblyDataItem> a)
        {
            var simpleToFullName = new MultiDict<string, string>();
            foreach (var method in asmDataItem.cecilType.Methods)
            {
                if (!method.IsPublic)
                    continue;
                // we'll ignore property getter/setter
                if (method.Name.StartsWith("set") || method.Name.StartsWith("get"))
                    continue;

                var simplifiedMemberName = MemberNameFromMethodDefinition(method, true);
                simplifiedMemberName = string.Format("{0}.{1}", asmDataItem.ItemName(), simplifiedMemberName);

                var fullMemberName = MemberNameFromMethodDefinition(method, false);

                if (!simpleToFullName.Contains(simplifiedMemberName))
                    simpleToFullName.Add(simplifiedMemberName, fullMemberName);
            }

            foreach (var simplifiedMemberName in simpleToFullName.Keys)
            {
                var methodAsm = new AssemblyDataItem(AssemblyType.Method, asmDataItem.cecilType, asmDataItem);
                //{MInfo = method};
                methodAsm.SimplifiedName = simplifiedMemberName;

                AddAssemblyDataItem(a, methodAsm);
            }
        }