/// <summary>
        /// Performs some basic screening and invokes the <see cref="IProxyGenerationHook"/>
        /// to select methods.
        /// </summary>
        /// <param name="method"></param>
        /// <param name="onlyVirtuals"></param>
        /// <param name="hook"></param>
        /// <returns></returns>
        protected bool AcceptMethod(MethodInfo method, bool onlyVirtuals, IProxyGenerationHook hook)
        {
            // we can never intercept a sealed (final) method
            if (method.IsFinal)
            {
                Logger.Debug("Excluded sealed method {0} on {1} because it cannot be intercepted.", method.Name, method.DeclaringType.FullName);
                return(false);
            }

            bool isInternalsAndNotVisibleToDynamicProxy = InternalsHelper.IsInternal(method);

            if (isInternalsAndNotVisibleToDynamicProxy)
            {
                isInternalsAndNotVisibleToDynamicProxy = InternalsHelper.IsInternalToDynamicProxy(method.DeclaringType.Assembly) ==
                                                         false;
            }

            if (isInternalsAndNotVisibleToDynamicProxy)
            {
                return(false);
            }

            if (onlyVirtuals && !method.IsVirtual)
            {
#if SILVERLIGHT
                if (method.DeclaringType != typeof(object))
#else
                if (method.DeclaringType != typeof(object) && method.DeclaringType != typeof(MarshalByRefObject))
#endif
                {
                    Logger.Debug("Excluded non-virtual method {0} on {1} because it cannot be intercepted.", method.Name, method.DeclaringType.FullName);
                    hook.NonVirtualMemberNotification(type, method);
                }

                return(false);
            }

            //can only proxy methods that are public or protected (or internals that have already been checked above)
            if ((method.IsPublic || method.IsFamily || method.IsAssembly || method.IsFamilyOrAssembly) == false)
            {
                return(false);
            }

            if (method.DeclaringType == typeof(object))
            {
                return(false);
            }

#if !SILVERLIGHT
            if (method.DeclaringType == typeof(MarshalByRefObject))
            {
                return(false);
            }
#endif
            return(hook.ShouldInterceptMethod(type, method));
        }
        private MethodAttributes ObtainAttributes()
        {
            var methodInfo = Method;
            var attributes = MethodAttributes.Virtual;

            if (methodInfo.IsFinal || Method.DeclaringType.IsInterface)
            {
                attributes |= MethodAttributes.NewSlot;
            }

            if (methodInfo.IsPublic)
            {
                attributes |= MethodAttributes.Public;
            }

            if (methodInfo.IsHideBySig)
            {
                attributes |= MethodAttributes.HideBySig;
            }
            if (InternalsHelper.IsInternal(methodInfo) &&
                InternalsHelper.IsInternalToDynamicProxy(methodInfo.DeclaringType.Assembly))
            {
                attributes |= MethodAttributes.Assembly;
            }
            if (methodInfo.IsFamilyAndAssembly)
            {
                attributes |= MethodAttributes.FamANDAssem;
            }
            else if (methodInfo.IsFamilyOrAssembly)
            {
                attributes |= MethodAttributes.FamORAssem;
            }
            else if (methodInfo.IsFamily)
            {
                attributes |= MethodAttributes.Family;
            }

            if (Standalone == false)
            {
                attributes |= MethodAttributes.SpecialName;
            }
            return(attributes);
        }