/// <summary>
        /// Tries to perform an indexing "set" operation by checking methods and properties for the given indexName
        /// </summary>
        /// <param name="script">The script.</param>
        /// <param name="obj">The object.</param>
        /// <param name="indexName">Member name to be indexed.</param>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        protected virtual bool TrySetIndex(Script script, object obj, string indexName, DynValue value)
        {
            StandardUserDataPropertyDescriptor pdesc = m_Properties.GetOrDefault(indexName);

            if (pdesc != null)
            {
                pdesc.SetValue(script, obj, value);
                return(true);
            }
            else
            {
                StandardUserDataFieldDescriptor fdesc = m_Fields.GetOrDefault(indexName);

                if (fdesc != null)
                {
                    fdesc.SetValue(script, obj, value);
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="StandardUserDataDescriptor"/> class.
        /// </summary>
        /// <param name="type">The type this descriptor refers to.</param>
        /// <param name="accessMode">The interop access mode this descriptor uses for members access</param>
        /// <param name="friendlyName">A human readable friendly name of the descriptor.</param>
        protected internal StandardUserDataDescriptor(Type type, InteropAccessMode accessMode, string friendlyName)
        {
            if (Script.GlobalOptions.Platform.IsRunningOnAOT())
            {
                accessMode = InteropAccessMode.Reflection;
            }

            if (accessMode == InteropAccessMode.Default)
            {
                accessMode = UserData.DefaultAccessMode;
            }

            Type         = type;
            Name         = type.FullName;
            AccessMode   = accessMode;
            FriendlyName = friendlyName;

            if (AccessMode != InteropAccessMode.HideMembers)
            {
                // get first constructor
                StandardUserDataOverloadedMethodDescriptor constructors = null;

                foreach (ConstructorInfo ci in type.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static))
                {
                    StandardUserDataMethodDescriptor md = StandardUserDataMethodDescriptor.TryCreateIfVisible(ci, this.AccessMode);

                    if (md != null)
                    {
                        if (constructors == null)
                        {
                            constructors = new StandardUserDataOverloadedMethodDescriptor("__new", this.Type)
                            {
                                IgnoreExtensionMethods = true
                            }
                        }
                        ;
                        constructors.AddOverload(md);
                    }
                }

                // valuetypes don't reflect their empty ctor.. actually empty ctors are a perversion, we don't care and implement ours
                if (type.IsValueType)
                {
                    if (constructors == null)
                    {
                        constructors = new StandardUserDataOverloadedMethodDescriptor("__new", this.Type);
                    }

                    constructors.AddOverload(new StandardUserDataMethodDescriptor(type, accessMode));
                }

                if (constructors != null)
                {
                    m_Methods.Add("__new", constructors);
                }

                // get methods
                foreach (MethodInfo mi in type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static))
                {
                    StandardUserDataMethodDescriptor md = StandardUserDataMethodDescriptor.TryCreateIfVisible(mi, this.AccessMode);

                    if (md != null)
                    {
                        if (!StandardUserDataMethodDescriptor.CheckMethodIsCompatible(mi, false))
                        {
                            continue;
                        }

                        Dictionary <string, StandardUserDataOverloadedMethodDescriptor> dic = m_Methods;

                        string name = mi.Name;
                        if (mi.IsSpecialName && (mi.Name == CASTINGS_EXPLICIT || mi.Name == CASTINGS_IMPLICIT))
                        {
                            name = GetConversionMethodName(mi.ReturnType);
                        }

                        if (m_Methods.ContainsKey(name))
                        {
                            m_Methods[name].AddOverload(md);
                        }
                        else
                        {
                            m_Methods.Add(name, new StandardUserDataOverloadedMethodDescriptor(name, this.Type, md));
                        }

                        foreach (string metaname in GetMetaNamesFromAttributes(mi))
                        {
                            if (m_MetaMethods.ContainsKey(metaname))
                            {
                                m_MetaMethods[metaname].AddOverload(md);
                            }
                            else
                            {
                                m_MetaMethods.Add(metaname, new StandardUserDataOverloadedMethodDescriptor(metaname, this.Type, md)
                                {
                                    IgnoreExtensionMethods = true
                                });
                            }
                        }
                    }
                }

                // get properties
                foreach (PropertyInfo pi in type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static))
                {
                    if (pi.IsSpecialName || pi.GetIndexParameters().Any())
                    {
                        continue;
                    }

                    var pd = StandardUserDataPropertyDescriptor.TryCreateIfVisible(pi, this.AccessMode);
                    if (pd != null)
                    {
                        m_Properties.Add(pd.Name, pd);
                    }
                }

                // get fields
                foreach (FieldInfo fi in type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static))
                {
                    if (fi.IsSpecialName)
                    {
                        continue;
                    }

                    var fd = StandardUserDataFieldDescriptor.TryCreateIfVisible(fi, this.AccessMode);
                    if (fd != null)
                    {
                        m_Fields.Add(fd.Name, fd);
                    }
                }

                // get events
                foreach (EventInfo ei in type.GetEvents(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static))
                {
                    if (ei.IsSpecialName)
                    {
                        continue;
                    }

                    var ed = StandardUserDataEventDescriptor.TryCreateIfVisible(ei, this.AccessMode);
                    if (ed != null)
                    {
                        m_Events.Add(ei.Name, ed);
                    }
                }
            }
        }