// TODO: return the descriptor corresponding to the properties you want to show
        public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object component, Attribute[] attributes)
        {
            PropertyDescriptorCollection props = new PropertyDescriptorCollection(null);
            //Console.WriteLine("Events comp: " + component.GetType().FullName);
            FieldsProxy proxy = component as FieldsProxy;
            if (proxy.GetTarget() is Model)
            {
                Model model = proxy.GetTarget() as Model;
                if (model.Prototype == false) return props;  // GameObjects cannot have their own events 
            }

            if (proxy != null)
            {
                //                 foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(proxy.GetTarget(), false))
                //                 {
                //                     Console.WriteLine("Events prop: " + prop.Name);
                //                     if (prop.IsReadOnly == false)
                //                         props.Add(prop);
                //                 }
                foreach (FieldInfo field in proxy.GetTarget().GetType().GetFields(BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance))
                {
                    if (field.FieldType.IsSubclassOf(typeof(CodeLike)))
                    {
                        FieldPropertyDescriptor fieldDesc = new FieldPropertyDescriptor(field);
                        props.Add(fieldDesc);
                    }
                }
                foreach (EventInfo ev in proxy.GetTarget().GetType().GetEvents(BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance))
                {
                    EventPropertyDescriptor eventDesc = new EventPropertyDescriptor(ev);
                    props.Add(eventDesc);
                }
            }

            return props;
        }
        PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes)
        {
            bool filtering = (attributes != null && attributes.Length > 0);
            PropertyDescriptorCollection props = _propCache;
            FilterCache cache = _filterCache;

            // Use a cached version if we can
            if (filtering && cache != null && cache.IsValid(attributes))
            {
                return cache.FilteredProperties;
            }
            else if (!filtering && props != null)
            {
                return props;
            }

            // Create the property collection and filter if necessary
            props = new PropertyDescriptorCollection(null);
            foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(_target, attributes, true))
            {
                if (prop.IsReadOnly == false)
                    props.Add(prop);
            }
            foreach (FieldInfo field in _target.GetType().GetFields(BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance))
            {
                FieldPropertyDescriptor fieldDesc = new FieldPropertyDescriptor(field);
                if (!filtering || fieldDesc.Attributes.Contains(attributes)) props.Add(fieldDesc);
            }

            // Store the computed properties
            if (filtering)
            {
                cache = new FilterCache();
                cache.Attributes = attributes;
                cache.FilteredProperties = props;
                _filterCache = cache;
            }
            else _propCache = props;

            return props;
        }