context: using System;
  using System.Collections.Generic;
  using WCell.RealmServer.Database.Entities;
  using WCell.Util.Logging;
  using WCell.Constants;
  using WCell.Constants.Items;
  using WCell.Constants.Looting;
  using WCell.Constants.Updates;
  using WCell.Core;
  using WCell.RealmServer.Database;
  using WCell.RealmServer.Handlers;
  using WCell.RealmServer.Items;
  using WCell.RealmServer.Items.Enchanting;
  using WCell.RealmServer.Misc;
  using WCell.RealmServer.Modifiers;
  using WCell.RealmServer.Quests;
  using WCell.Util;
  using WCell.Util.Threading;
  
  namespace WCell.RealmServer.Entities
  {
  	public partial class Item : ObjectBase, IOwned, IWeapon, INamed, ILockable, IQuestHolder, IMountableItem, IContextHandler
  	{
  		private static readonly Logger log = LogManager.GetCurrentClassLogger();
  
  		public static readonly UpdateFieldCollection UpdateFieldInfos = UpdateFieldMgr.Get(ObjectTypeId.Item);
  
  		protected override UpdateFieldCollection _UpdateFieldInfos
  		{
  			get { return UpdateFieldInfos; }
  		}
  
  		public static readonly Item PlaceHolder = new Item();
  
  		protected ItemTemplate m_template;
  		protected internal bool m_isInWorld;
  
  		/// <summary>
  		/// Items are unknown when a creation update
  		/// has not been sent to the Owner yet.
  		/// </summary>
  		internal bool m_unknown;
  
  		protected internal Character m_owner;
  		protected BaseInventory m_container;
  		protected ItemEnchantment[] m_enchantments;
  		protected IProcHandler m_hitProc;
  		protected ItemRecord m_record;
  
  		#region CreateItem
  		public static Item CreateItem(uint templateId, Character owner, int amount)
  		{
  			var template = ItemMgr.GetTemplate(templateId);
  			if (template != null)
  			{
  				return CreateItem(template, owner, amount);
  			}
  			return null;
  		}
  
  		public static Item CreateItem(ItemId templateId, Character owner, int amount)
  		{
  			var template = ItemMgr.GetTemplate(templateId);
  			if (template != null)
  			{
  				return CreateItem(template, owner, amount);
  			}
  			return null;
  		}
  
  		public static Item CreateItem(ItemTemplate template, Character owner, int amount)
  		{
  			var item = template.Create();
  			item.InitItem(template, owner, amount);
  			return item;
  		}
  
  		public static Item CreateItem(ItemRecord record, Character owner)
  		{
  			var template = record.Template;
  			if (template == null)
  			{
  				log.Warn("{0} had an ItemRecord with invalid ItemId: {1}", owner, record);
  				return null;
  			}
  
  			var item = template.Create();
  			item.LoadItem(record, owner, template);
  			return item;
  		}
  
  		public static Item CreateItem(ItemRecord record, Character owner, ItemTemplate template)
  		{
  			var item = template.Create();
  			item.LoadItem(record, owner, template);
  			return item;
  		}
  
  		public static Item CreateItem(ItemRecord record, ItemTemplate template)
  		{
  			var item = template.Create();
  			item.LoadItem(record, template);
  			return item;
  		}
  		#endregion
  
  		protected internal Item()
  		{
  		}
  
  		#region Init & Load
  		/// <summary>
  		/// Initializes a new Item
  		/// </summary>
  		internal void InitItem(ItemTemplate template, Character owner, int amount)
  		{
  			m_record = ItemRecord.CreateRecord();
  
  			EntryId = m_record.EntryId = template.Id;
  
  			Type |= ObjectTypes.Item;
  
  			m_template = template;
  
  			Durability = m_template.MaxDurability;
  			MaxDurability = m_template.MaxDurability;
  			Flags = m_template.Flags;
  			TextId = m_template.PageTextId;
  			Amount = amount;
  			OwningCharacter = owner;
  			EntityId = m_record.EntityId;
  
  			// set charges to max
  			if (m_template.UseSpell != null && m_template.UseSpell.HasCharges)
  			{
  				m_record.Charges = m_template.UseSpell.Charges;
  				SetSpellCharges(m_template.UseSpell.Index, m_template.UseSpell.Charges);
  			}
  
  			var randomEnchants = m_template.RandomPrefixes;
  			if (randomEnchants != null)
  			{
  				ApplyRandomEnchants(randomEnchants, EnchantSlot.PropSlot2, EnchantSlot.PropSlot4);
  			}
  			randomEnchants = m_template.RandomSuffixes;
  			if (randomEnchants != null)
  			{
  				if (ApplyRandomEnchants(randomEnchants, EnchantSlot.PropSlot0, EnchantSlot.PropSlot2))
  				{
  					RandomPropertiesId = m_enchantments[(int)EnchantSlot.PropSlot0].Entry.Id;
  				}
  			}
  
  			template.NotifyCreated(m_record);
  			OnInit();
  		}
  
  		/// <summary>
  		/// Loads an already created item
  		/// </summary>
  		internal void LoadItem(ItemRecord record, Character owner, ItemTemplate template)
  		{
  			m_record = record;
  			OwningCharacter = owner;
  
  			LoadItem(record, template);
  		}
  
  		/// <summary>
  		/// Loads an already created item without owner
  		/// </summary>
  		/// <param name="record"></param>
  		/// <param name="template"></param>
  		internal void LoadItem(ItemRecord record, ItemTemplate template)
  		{
  			m_record = record;
  			EntityId = record.EntityId;
  
  			m_template = template;
  			EntryId = m_template.Id;
  
  			Type |= ObjectTypes.Item;
  
  			SetUInt32(ItemFields.FLAGS, (uint)record.Flags);
  			SetInt32(ItemFields.DURABILITY, record.Durability);
  			SetInt32(ItemFields.DURATION, record.Duration);
  			SetInt32(ItemFields.STACK_COUNT, record.Amount);
  			SetInt32(ItemFields.PROPERTY_SEED, record.RandomSuffix);
  			SetInt32(ItemFields.RANDOM_PROPERTIES_ID, record.RandomProperty);
  			SetInt64(ItemFields.CREATOR, record.CreatorEntityId);
  			SetInt64(ItemFields.GIFTCREATOR, record.GiftCreatorEntityId);
  
  			ItemText = record.ItemText;
  
  			if (m_template.UseSpell != null)
  			{
  				SetSpellCharges(m_template.UseSpell.Index, (int)record.Charges);
  			}
  			MaxDurability = m_template.MaxDurability;
  
  			// add enchants
  
gt: 			if (record.EnchantIds != null)