#region Native Methods
		[DllImport("gmime")]
		static extern int g_mime_multipart_get_count (IntPtr multipart);
		
		[DllImport("gmime")]
		static extern void g_mime_multipart_clear (IntPtr multipart);
		
		[DllImport("gmime")]
		static extern int g_mime_multipart_add (IntPtr multipart, IntPtr part);
		
		[DllImport("gmime")]
		static extern void g_mime_multipart_insert (IntPtr multipart, int index, IntPtr part);
		
		[DllImport("gmime")]
		static extern bool g_mime_multipart_remove (IntPtr multipart, IntPtr part);
		
		[DllImport("gmime")]
		static extern bool g_mime_multipart_remove_at (IntPtr multipart, int index);
		
		[DllImport("gmime")]
		static extern bool g_mime_multipart_contains (IntPtr multipart, IntPtr part);
		
		[DllImport("gmime")]
		static extern int g_mime_multipart_index_of (IntPtr multipart, IntPtr part);
		
		[DllImport("gmime")]
		static extern IntPtr g_mime_multipart_get_part (IntPtr multipart, int index);
#endregion
		
		Exception CannotAdd (object value)
		{
			if (value == null)
				return new ArgumentNullException ("value");
			
			string message = String.Format ("Cannot add objects of type '{0}' to a GMime.Multipart.",
							value.GetType ().ToString ());
			
			return new InvalidOperationException (message);
		}
		
		Exception CannotInsert (object value)
		{
			if (value == null)
				return new ArgumentNullException ("value");
			
			string message = String.Format ("Cannot insert objects of type '{0}' into a GMime.Multipart.",
							value.GetType ().ToString ());
			
			return new InvalidOperationException (message);
		}
		
		Exception CannotRemove (object value)
		{
			if (value == null)
				return new ArgumentNullException ("value");
			
			string  message = String.Format ("Cannot remove objects of type '{0}' from a GMime.Multipart.",
							 value.GetType ().ToString ());
			
			return new InvalidOperationException (message);
		}
		
		Exception CannotSet (object value)
		{
			if (value == null)
				return new ArgumentNullException ("value");
			
			string message = String.Format ("Cannot set objects of type '{0}' on a GMime.Multipart.",
							value.GetType ().ToString ());
			
			return new InvalidOperationException (message);
		}
		
		public int Count { 
			get { return g_mime_multipart_get_count (Handle); }
		}
		
		public bool IsFixedSize {
			get { return false; }
		}
		
		public bool IsReadOnly {
			get { return false; }
		}
		
		public bool IsSynchronized {
			get { return false; }
		}
		
		public object SyncRoot {
			get { return this; }
		}
		
		public int Add (GMime.Entity part)
		{
			if (part == null)
				throw CannotAdd (part);
			
			return g_mime_multipart_add (Handle, part.Handle);
		}
		
		int IList.Add (object value)
		{
			GMime.Entity part = value as GMime.Entity;
			
			if (part == null)
				throw CannotAdd (value);
			
			return Add (part);
		}
		
		public void Clear ()
		{
			g_mime_multipart_clear (Handle);
		}
		
		public bool Contains (GMime.Entity part)
		{
			if (part == null)
				return false;
			
			return g_mime_multipart_contains (Handle, part.Handle);
		}
		
		bool IList.Contains (object value)
		{
			return Contains (value as GMime.Entity);
		}
		
		public void CopyTo (Array array, int index)
		{
			if (array == null)
				throw new ArgumentNullException ("array");
			
			if (index < 0)
				throw new ArgumentOutOfRangeException ("index");
			
			int n = Count;
			
			for (int i = 0; i < n; i++)
				array.SetValue (((IList) this)[i], index + i);
		}
		
		public IEnumerator GetEnumerator ()
		{
			int n = Count;
			
			for (int i = 0; i < n; i++)
				yield return this[i];
			
			yield break;
		}
		
		public int IndexOf (GMime.Entity part)
		{
			if (part == null)
				return -1;
			
			return g_mime_multipart_index_of (Handle, part.Handle);
		}
		
		int IList.IndexOf (object value)
		{
			return IndexOf (value as GMime.Entity);
		}
		
		public void Insert (int index, GMime.Entity part)
		{
			if (part == null)
				throw CannotInsert (part);
			
			if (index < 0)
				throw new ArgumentOutOfRangeException ("index");
			
			g_mime_multipart_insert (Handle, index, part.Handle);
		}
		
		void IList.Insert (int index, object value)
		{
			GMime.Entity part = value as GMime.Entity;
			
			if (part == null)
				throw CannotInsert (value);
			
			Insert (index, part);
		}
		
		public void Remove (GMime.Entity part)
		{
			if (part == null)
				throw CannotRemove (part);
			
			g_mime_multipart_remove (Handle, part.Handle);
		}
		
		void IList.Remove (object value)
		{
			GMime.Entity part = value as GMime.Entity;
			
			if (part == null)
				throw CannotRemove (value);
			
			Remove (part);
		}
		
		public void RemoveAt (int index)
		{
			if (index < 0 || index >= Count)
				throw new ArgumentOutOfRangeException ("index");
			
			g_mime_multipart_remove_at (Handle, index);
		}
		
		public GMime.Entity this[int index] {
			get {
				IntPtr raw = g_mime_multipart_get_part (Handle, index);
				
				if (raw == IntPtr.Zero)
					return null;
				
				return GLib.Object.GetObject (raw) as GMime.Entity;
			}
			
			set {
				if (value == null)
					throw CannotSet (value);
				
				if (index > Count || index < Count)
					throw new ArgumentOutOfRangeException ("index");
				
				if (index < Count) {
					RemoveAt (index);
					Insert (index, value);
				} else {
					Add (value);
				}
			}
		}
		
		object IList.this[int index] {
			get {
				return this[index];
			}
			
			set {
				this[index] = value as GMime.Entity;
			}
		}
