/// <summary>
        /// Dispose event handler.
        /// </summary>
        /// <param name="sender">Core object being disposed.</param>
        void core_Dispose(ProtoCore.Core sender)
        {
            CLRObjectMarshler marshaller = null;

            if (!mObjectMarshlers.TryGetValue(sender, out marshaller))
            {
                throw new KeyNotFoundException();
            }

            mObjectMarshlers.Remove(sender);

            //Detach from core.
            sender.Dispose -= core_Dispose;

            //Dispose all disposable CLR objects.
            foreach (var item in DSObjectMap)
            {
                IDisposable disposable = item.Value as IDisposable;
                sender.FFIPropertyChangedMonitor.RemoveFFIObject(item.Value);

                if (null != disposable)
                {
                    disposable.Dispose();
                }
            }

            //Clear the maps.
            DSObjectMap.Clear();
            CLRObjectMap.Clear();
        }
 /// <summary>
 ///
 /// </summary>
 /// <param name="dsObject"></param>
 /// <param name="context"></param>
 /// <param name="dsi"></param>
 public override void OnDispose(StackValue dsObject, ProtoCore.Runtime.Context context, Interpreter dsi)
 {
     lock (DSObjectMap)
     {
         Object clrobject;
         if (DSObjectMap.TryGetValue(dsObject, out clrobject))
         {
             DSObjectMap.Remove(dsObject);
             CLRObjectMap.Remove(clrobject);
             dsi.runtime.Core.FFIPropertyChangedMonitor.RemoveFFIObject(clrobject);
         }
     }
 }
        /// <summary>
        ///
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="context"></param>
        /// <param name="dsi"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public override StackValue Marshal(object obj, ProtoCore.Runtime.Context context, Interpreter dsi, ProtoCore.Type type)
        {
            if (obj == null)
            {
                return(StackUtils.BuildNull());
            }

            FFIObjectMarshler marshaler = null;
            StackValue        retVal;
            Type objType = obj.GetType();

            if (type.IsIndexable)
            {
                if (obj is System.Collections.ICollection)
                {
                    System.Collections.ICollection collection = obj as System.Collections.ICollection;
                    object[] array = new object[collection.Count];
                    collection.CopyTo(array, 0);
                    return(PrimitiveMarshler.ConvertCSArrayToDSArray(this, array, context, dsi, type));
                }
                else if (obj is System.Collections.IEnumerable)
                {
                    System.Collections.IEnumerable enumerable = obj as System.Collections.IEnumerable;
                    return(PrimitiveMarshler.ConvertCSArrayToDSArray(this, enumerable, context, dsi, type));
                }
            }

            Array arr = obj as Array;

            if (null != arr)
            {
                return(PrimitiveMarshler.ConvertCSArrayToDSArray(this, arr, context, dsi, type));
            }
            else if ((PrimitiveMarshler.IsPrimitiveDSType(type) || PrimitiveMarshler.IsPrimitiveObjectType(obj, type)) && mPrimitiveMarshalers.TryGetValue(objType, out marshaler))
            {
                return(marshaler.Marshal(obj, context, dsi, type));
            }
            else if (CLRObjectMap.TryGetValue(obj, out retVal))
            {
                return(retVal);
            }

            return(CreateDSObject(obj, context, dsi));
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="dsobj"></param>
        private void BindObjects(object obj, StackValue dsobj)
        {
#if DEBUG
            if (DSObjectMap.ContainsKey(dsobj))
            {
                throw new InvalidOperationException("Object reference already mapped");
            }

            if (CLRObjectMap.ContainsKey(obj))
            {
                throw new InvalidOperationException("Object reference already mapped");
            }
#endif
            lock (DSObjectMap)
            {
                DSObjectMap[dsobj] = obj;
                CLRObjectMap[obj]  = dsobj;
            }
        }