public bool Equals(GenericKey other)
 {
     return(TypeDefinition.Equals(other.TypeDefinition) && GenericArguments.Equals(other.GenericArguments));
 }
        protected sealed override Delegate RemoveImpl(Delegate value)
        {
            if (value == null)
            {
                return(this);
            }

            MulticastDelegate other = (MulticastDelegate)value;

            if (delegates == null && other.delegates == null)
            {
                /* if they are not equal and the current one is not
                 * a multicastdelegate then we cannot delete it */
                return(this.Equals(other) ? null : this);
            }
            else if (delegates == null)
            {
                foreach (var d in other.delegates)
                {
                    if (this.Equals(d))
                    {
                        return(null);
                    }
                }
                return(this);
            }
            else if (other.delegates == null)
            {
                int idx = Array.LastIndexOf(delegates, other);
                if (idx == -1)
                {
                    return(this);
                }

                if (delegates.Length <= 1)
                {
                    /* delegates.Length should never be equal or
                    * lower than 1, it should be 2 or greater */
                    throw new InvalidOperationException();
                }

                if (delegates.Length == 2)
                {
                    return(delegates [idx == 0 ? 1 : 0]);
                }

                MulticastDelegate ret = AllocDelegateLike_internal(this);
                ret.delegates = new Delegate [delegates.Length - 1];

                Array.Copy(delegates, ret.delegates, idx);
                Array.Copy(delegates, idx + 1, ret.delegates, idx, delegates.Length - idx - 1);

                return(ret);
            }
            else
            {
                /* wild case : remove MulticastDelegate from MulticastDelegate
                 * complexity is O(m + n), with n the number of elements in
                 * this.delegates and m the number of elements in other.delegates */

                if (delegates.Equals(other.delegates))
                {
                    return(null);
                }

                /* we need to remove elements from the end to the beginning, as
                * the addition and removal of delegates behaves like a stack */
                int idx = LastIndexOf(delegates, other.delegates);
                if (idx == -1)
                {
                    return(this);
                }

                MulticastDelegate ret = AllocDelegateLike_internal(this);
                ret.delegates = new Delegate [delegates.Length - other.delegates.Length];

                Array.Copy(delegates, ret.delegates, idx);
                Array.Copy(delegates, idx + other.delegates.Length, ret.delegates, idx, delegates.Length - idx - other.delegates.Length);

                return(ret);
            }
        }