public static NovaBoxedInstance Box(object obj, NovaScope scope = null)
        {
            if (obj == null)
            {
                return(null);
            }
            if (_boxCache.ContainsKey(obj))
            {
                _boxCache[obj].BoxedScope.MergeWithScope(scope ?? new NovaScope());
                return(_boxCache[obj]);
            }
            var boxed = new NovaBoxedInstance(obj, scope ?? new NovaScope());

            _boxCache[obj] = boxed;
            if (scope != null)
            {
                string name;
                var    _scope = scope.SearchForObject(obj, out name);
                if (_scope != null)
                {
                    _scope[name] = boxed;
                }
            }
            return(boxed);
        }
            public override DynamicMetaObject BindGetMember(GetMemberBinder binder)
            {
                if (!(Value is NovaBoxedInstance) && Value.BackingObject != null)
                {
                    NovaBoxedInstance.SyncInstanceVariablesFrom(Value, Value.BackingObject);
                }
                var dmo = InteropBinder.GetMember.Bind(new InteropBinder.GetMember(binder.Name, Scope),
                                                       this);

                if (!(Value is NovaBoxedInstance) && Value.BackingObject != null)
                {
                    NovaBoxedInstance.SyncInstanceVariablesTo(Value, Value.BackingObject);
                }
                return(dmo);
            }
            public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder,
                                                               params DynamicMetaObject[] args)
            {
                if (!(Value is NovaBoxedInstance) && Value.BackingObject != null)
                {
                    NovaBoxedInstance.SyncInstanceVariablesFrom(Value, Value.BackingObject);
                }
                var dmo =
                    InteropBinder.InvokeMember.Bind(
                        new InteropBinder.InvokeMember(binder.Name, binder.CallInfo, Scope), this, args);

                if (!(Value is NovaBoxedInstance) && Value.BackingObject != null)
                {
                    NovaBoxedInstance.SyncInstanceVariablesTo(Value, Value.BackingObject);
                }
                return(dmo);
            }
        public static NovaBoxedInstance BoxNoCache(object obj, NovaScope scope = null)
        {
            if (obj == null)
            {
                return(null);
            }
            var boxed = new NovaBoxedInstance(obj, scope ?? new NovaScope());

            if (scope != null)
            {
                string name;
                var    _scope = scope.SearchForObject(obj, out name);
                if (_scope != null)
                {
                    _scope[name] = boxed;
                }
            }
            return(boxed);
        }
 public static dynamic Unbox(NovaBoxedInstance obj)
 {
     _boxCache.Remove(obj.BoxedObject);
     return(obj.BoxedObject);
 }