context: using Microsoft.Xml.Serialization.GeneratedAssembly;
  
  using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.IO;
  using System.Linq;
  using System.Xml;
  using System.Reflection;
  using Sandbox.Common.ObjectBuilders.Definitions;
  
  namespace SEModAPI.API.Definitions
  {
  	/// <summary>
  	/// This class is only intended for easy data access and management. It is a wrapper around all MyObjectBuilder_Definitions children sub type
  	/// </summary>
  	public abstract class OverLayerDefinition<T>
  	{
  		#region "Attributes"
  
  		protected T m_baseDefinition;
  		protected string m_name;
  
  		#endregion
  
  		#region "Constructors and Initializers"
  
  		protected OverLayerDefinition(T baseDefinition)
  		{
  			m_baseDefinition = baseDefinition;
  			m_name = GetNameFrom(m_baseDefinition);
  			Changed = false;
  		}
  
  		#endregion
  
  		#region "Properties"
  
  		/// <summary>
  		/// Gets the changed status of the object
  		/// </summary>
  		[Browsable(false)]
  		public bool Changed { get; protected set; }
  
  		/// <summary>
  		/// Obtain a nicely formated name of the object
  		/// </summary>
  		[Browsable(false)]
  		public string Name
  		{
  			get { return GetNameFrom(m_baseDefinition); }
  		}
  
  		/// <summary>
  		/// Gets the internal data of the object
  		/// </summary>
  		[Browsable(false)]
  		public T BaseDefinition
  		{
  			get { return m_baseDefinition; }
  		}
  
  		#endregion
  
  		#region "Methods"
  
  		/// <summary>
  		/// This template method should return the representative name of the sub type underlayed by a children
  		/// </summary>
  		/// <param name="definition">The definition from which to get the information</param>
  		/// <returns></returns>
  		protected abstract string GetNameFrom(T definition);
  
  		#endregion
  	}
  
  	public abstract class ObjectOverLayerDefinition<TMyObjectBuilder_Definitions_SubType> : OverLayerDefinition<TMyObjectBuilder_Definitions_SubType> where TMyObjectBuilder_Definitions_SubType : MyObjectBuilder_DefinitionBase
  	{
  		#region "Constructors and Initializers"
  
  		protected ObjectOverLayerDefinition(TMyObjectBuilder_Definitions_SubType baseDefinition)
  			: base(baseDefinition)
  		{ }
  
  		#endregion
  
  		#region "Properties"
  
  		public SerializableDefinitionId Id
  		{
  			get { return m_baseDefinition.Id; }
  			set
  			{
  				if (m_baseDefinition.Id.ToString() == value.ToString()) return;
  				m_baseDefinition.Id = value;
  				Changed = true;
  			}
  		}
  
  		public string Description
  		{
  			get { return m_baseDefinition.Description; }
  			set
  			{
  				if (m_baseDefinition.Description == value) return;
  				m_baseDefinition.Description = value;
  				Changed = true;
  			}
  		}
  
  		#endregion
  	}
  
  
  	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  
  	public abstract class OverLayerDefinitionsManager<T, TU> where TU : OverLayerDefinition<T>
  	{
  		#region "Attributes"
  
  		private bool m_isMutable = true;
  		private bool m_changed = false;
  
  		//Use Long (key) as Id and OverLayerDefinition sub type (value) as Name
  		//For entity objects (saved game data) we use EntityId as the long key
  		private readonly Dictionary<long, TU> m_definitions = new Dictionary<long, TU>();
  
  		#endregion
  
  		#region "Constructors and Initializers"
  
  		protected OverLayerDefinitionsManager()
  		{
  			m_changed = false;
  			m_isMutable = true;
  		}
  
  		protected OverLayerDefinitionsManager(IEnumerable<T> baseDefinitions)
  		{
  			m_changed = false;
  			m_isMutable = true;
  
  			foreach (T definition in baseDefinitions)
  			{
  				NewEntry(definition);
  			}
  		}
  
  		#endregion
  
  		#region "Properties"
  
  		public bool IsMutable
  		{
  			get { return m_isMutable; }
  			set { m_isMutable = value; }
  		}
  
  		protected bool Changed
  		{
  			get
  			{
  				if (m_changed) return true;
  				return GetInternalData( ).Any( def => GetChangedState( def.Value ) );
  			}
  		}
  
  		public TU[] Definitions
  		{
  			get
  			{
  				return GetInternalData().Values.ToArray();
  			}
  		}
  
  		#endregion
  
  		#region "Methods"
  
  		protected virtual Dictionary<long, TU> GetInternalData()
  		{
  			return m_definitions;
  		}
  
  		/// <summary>
  		/// This method is used to extract all instances of MyObjectBuilder_Definitions sub type encapsulated in the manager
  		/// This method is slow and should only be used to extract the underlying type
  		/// </summary>
  		/// <returns>All instances of the MyObjectBuilder_Definitions sub type sub type in the manager</returns>
  		public List<T> ExtractBaseDefinitions()
  		{
  			return GetInternalData( ).Values.Select( GetBaseTypeOf ).ToList( );
  		}
  
  		private bool IsIdValid(long id)
  		{
  			return GetInternalData().ContainsKey(id);
  		}
  
  		private bool IsIndexValid(int index)
  		{
  
gt: 			return (index < GetInternalData().Keys.Count && index >= 0);