tid_t type_builder_t::get_structure(const qstring name)
{
	tid_t struct_type_id = add_struc(BADADDR, name.c_str());
	if (struct_type_id != 0 || struct_type_id != -1)
	{
		struc_t * struc = get_struc(struct_type_id);
		if(struc != NULL)
		{
			opinfo_t opinfo;
			opinfo.tid = struct_type_id;

			int j = 0;
			
			for(std::map<int, struct_filed>::iterator i = structure.begin(); i != structure.end() ; i ++)
			{
				VTBL_info_t vtbl;

				flags_t member_flgs = 0;
				if(i->second.size == 1)
					member_flgs = byteflag();
				else if (i->second.size == 2)
					member_flgs = wordflag();
				else if (i->second.size == 4)
					member_flgs = dwrdflag();
				else if (i->second.size == 8)
					member_flgs = qwrdflag();

				char field_name[258];
				memset(field_name, 0x00, sizeof(field_name));

				if((i->second.vftbl != BADADDR) && get_vbtbl_by_ea(i->second.vftbl, vtbl)) 
				{
					qstring vftbl_name = name;
					vftbl_name.cat_sprnt("_VTABLE_%X_%p", i->second.offset, i->second.vftbl);

					tid_t vtbl_str_id = create_vtbl_struct(vtbl.ea_begin, vtbl.ea_end, (char *)vftbl_name.c_str(), 0);
					if (vtbl_str_id != BADADDR) {
						sprintf_s(field_name, sizeof(field_name), "vftbl_%d_%p", j, i->second.vftbl);
						int iRet = add_struc_member(struc, field_name, i->second.offset, member_flgs, NULL, i->second.size);

						member_t * membr = get_member_by_name(struc, field_name);
						if (membr != NULL) {
							tinfo_t new_type = create_typedef((char *)vftbl_name.c_str());
							if(new_type.is_correct()) {
								smt_code_t dd = set_member_tinfo2(struc, membr, 0, make_pointer(new_type), SET_MEMTI_COMPATIBLE);
							}
						}
					}	
				} 
				else 
				{
					sprintf_s(field_name, sizeof(field_name), "field_%X", i->second.offset);
					int iRet = add_struc_member(struc, field_name, i->second.offset, member_flgs, NULL, i->second.size);
				}
				j ++;
			}
		}
	}
	return struct_type_id;
}
tid_t idaapi merge_types(qvector<qstring> types_to_merge, qstring type_name) {
	tid_t struct_type_id = BADADDR;

	std::set<ea_t> offsets;

	if (types_to_merge.size() != 0) {
		struct_type_id = add_struc(BADADDR, type_name.c_str());
		if (struct_type_id != 0 || struct_type_id != BADADDR)
		{
			struc_t * struc = get_struc(struct_type_id);
			if (struc != NULL) {
				qvector<qstring>::iterator types_iter;
				for (types_iter = types_to_merge.begin(); types_iter != types_to_merge.end(); types_iter++) {

					tid_t type_id = get_struc_id((*types_iter).c_str());
					if (type_id != BADADDR) {
						struc_t * struc_type = get_struc(type_id);
						if (struc_type != NULL) {
							// enumerate members
							for (ea_t offset = get_struc_first_offset(struc_type); offset != BADADDR; offset = get_struc_next_offset(struc_type, offset)) {
								member_t * member_info = get_member(struc_type, offset);
								if (member_info != NULL) {
									if (offsets.count(member_info->soff) == 0) {
										qstring member_name = get_member_name2(member_info->id);
										asize_t member_size = get_member_size(member_info);

										if (member_name.find("vftbl_", 0) != -1) {
											tinfo_t tif;
											if (get_member_tinfo2(member_info, &tif)) {
												add_struc_member(struc, member_name.c_str(), member_info->soff, dwrdflag(), NULL, member_size);
												member_t * membr = get_member(struc, member_info->soff);
												if (membr != NULL) {
													set_member_tinfo2(struc, membr, 0, tif, SET_MEMTI_COMPATIBLE);
												}
											}
										}
										else {
											add_struc_member(struc, member_name.c_str(), member_info->soff, member_info->flag, NULL, member_size);
										}

										offsets.insert(member_info->soff);
									}
								}
							}
						}
					}
				}
			}
		}
	}

	return struct_type_id;
}