private template_class CreateTemplateClass(int offset)
        {
            definition_node dn = null;
            if (members.TryGetValue(offset, out dn))
                return dn as template_class;
            template_class tc = null;

            string name = br.ReadString();

            bool is_syn = br.ReadByte() == 1;

            using_namespace_list unl = new using_namespace_list();
            int using_count = br.ReadInt32();
            for (int i = 0; i < using_count; i++)
            {
                unl.AddElement(new using_namespace(br.ReadString()));
            }
            using_namespace_list unl2 = null;
            if (CanReadObject())
            {
                unl2 = new using_namespace_list();
                int using_count2 = br.ReadInt32();
                for (int i = 0; i < using_count2; i++)
                {
                    unl2.AddElement(new using_namespace(br.ReadString()));
                }
            }
            document doc = null;
            if (br.ReadByte() == 1)
            {
                doc = new document(Path.Combine(Path.GetDirectoryName(cur_doc.file_name),br.ReadString()));
            }

            SyntaxTree.SyntaxTreeStreamReader str = new SyntaxTree.SyntaxTreeStreamReader();
            str.br = br;
            SyntaxTree.type_declaration t_d = str._read_node() as SyntaxTree.type_declaration;

            int ext_count = br.ReadInt32();
            List<procedure_definition_info> pdi_list = new List<procedure_definition_info>(ext_count);
            for (int i = 0; i < ext_count; i++)
            {
                byte num = br.ReadByte();
                common_namespace_node c_m_n = cun.namespaces[num];
                SyntaxTree.syntax_tree_node stn = str._read_node();
                SyntaxTree.procedure_definition p_d = stn as SyntaxTree.procedure_definition;
                pdi_list.Add(new procedure_definition_info(c_m_n, p_d));
            }

            //(ssyy) Далее формируем список областей видимости, которые
            //подключаются к модулю. Вообще-то шаблоны классов этим
            //заниматься не должны, но кроме них этот список
            //никому не нужен (по состоянию на 01.06.2007).
            if (cun.scope.TopScopeArray.Length == 0)
            {
                cun.scope.TopScopeArray = MakeTopScopeArray(unl, pcu_file.interface_uses_count);
            }

            if (cun.implementation_scope.TopScopeArray.Length == 0 && unl2 != null)
            {
                //формируем implementation - область
                cun.implementation_scope.TopScopeArray = MakeTopScopeArray(unl2, pcu_file.incl_modules.Length);
            }

            tc = new template_class(t_d, name, cun.namespaces[0], doc, unl);
            tc.external_methods = pdi_list;
            tc.using_list2 = unl2;
            tc.is_synonym = is_syn;

            //members[offset] = tc;
            AddMember(tc, offset);
            
            cun.namespaces[0].scope.AddSymbol(name, new SymbolInfo(tc));

            return tc;
        }
        public template_class create_template_class(string name, byte[] tree)
        {
            Dictionary<string, template_class> tc_dict = null;
            template_class tc = null;
            if (compiled_tc_cache.TryGetValue(converted_namespace, out tc_dict) && tc_dict.TryGetValue(name, out tc))
                return tc;

            SyntaxTree.SyntaxTreeStreamReader str = new SyntaxTree.SyntaxTreeStreamReader();
            str.br = new System.IO.BinaryReader(new System.IO.MemoryStream(tree));
            SyntaxTree.type_declaration t_d = str._read_node() as SyntaxTree.type_declaration;
            tc = new template_class(t_d, name, converted_namespace, null, new using_namespace_list());
            tc.is_synonym = true;
            if (tc_dict == null)
            {
                tc_dict = new Dictionary<string, template_class>();
                compiled_tc_cache[converted_namespace] = tc_dict;
            }
            tc_dict[name] = tc;
            return tc;
        }