public override IType VisitParameterizedType(ParameterizedType type)
            {
                IType newType = base.VisitParameterizedType(type);

                if (newType != type && ConstraintsValid)
                {
                    // something was changed, so we need to validate the constraints
                    ParameterizedType newParameterizedType = newType as ParameterizedType;
                    if (newParameterizedType != null)
                    {
                        // C# 4.0 spec: §4.4.4 Satisfying constraints
                        var typeParameters = newParameterizedType.GetDefinition().TypeParameters;
                        for (int i = 0; i < typeParameters.Count; i++)
                        {
                            ITypeParameter tp      = typeParameters[i];
                            IType          typeArg = newParameterizedType.TypeArguments[i];
                            if (tp.HasReferenceTypeConstraint)
                            {
                                if (typeArg.IsReferenceType(overloadResolution.context) != true)
                                {
                                    ConstraintsValid = false;
                                }
                            }
                            if (tp.HasValueTypeConstraint)
                            {
                                if (typeArg.IsReferenceType(overloadResolution.context) != false)
                                {
                                    ConstraintsValid = false;
                                }
                                if (NullableType.IsNullable(typeArg))
                                {
                                    ConstraintsValid = false;
                                }
                            }
                            if (tp.HasDefaultConstructorConstraint)
                            {
                                ITypeDefinition def = typeArg.GetDefinition();
                                if (def != null && def.IsAbstract)
                                {
                                    ConstraintsValid = false;
                                }
                                ConstraintsValid &= typeArg.GetConstructors(
                                    overloadResolution.context,
                                    m => m.Parameters.Count == 0 && m.Accessibility == Accessibility.Public
                                    ).Any();
                            }
                            foreach (IType constraintType in tp.Constraints)
                            {
                                IType c = newParameterizedType.SubstituteInType(constraintType);
                                ConstraintsValid &= overloadResolution.IsConstraintConvertible(typeArg, c);
                            }
                        }
                    }
                }
                return(newType);
            }
            public override IType VisitParameterizedType(ParameterizedType type)
            {
                IType newType = base.VisitParameterizedType(type);

                if (newType != type && ConstraintsValid)
                {
                    // something was changed, so we need to validate the constraints
                    ParameterizedType newParameterizedType = newType as ParameterizedType;
                    if (newParameterizedType != null)
                    {
                        // C# 4.0 spec: §4.4.4 Satisfying constraints
                        var typeParameters = newParameterizedType.GetDefinition().TypeParameters;
                        for (int i = 0; i < typeParameters.Count; i++)
                        {
                            ITypeParameter tp      = typeParameters[i];
                            IType          typeArg = newParameterizedType.GetTypeArgument(i);
                            switch (typeArg.Kind)                               // void, null, and pointers cannot be used as type arguments
                            {
                            case TypeKind.Void:
                            case TypeKind.Null:
                            case TypeKind.Pointer:
                                ConstraintsValid = false;
                                break;
                            }
                            if (tp.HasReferenceTypeConstraint)
                            {
                                if (typeArg.IsReferenceType(context) != true)
                                {
                                    ConstraintsValid = false;
                                }
                            }
                            if (tp.HasValueTypeConstraint)
                            {
                                if (!NullableType.IsNonNullableValueType(typeArg, context))
                                {
                                    ConstraintsValid = false;
                                }
                            }
                            if (tp.HasDefaultConstructorConstraint)
                            {
                                ITypeDefinition def = typeArg.GetDefinition();
                                if (def != null && def.IsAbstract)
                                {
                                    ConstraintsValid = false;
                                }
                                ConstraintsValid &= typeArg.GetConstructors(
                                    context,
                                    m => m.Parameters.Count == 0 && m.Accessibility == Accessibility.Public,
                                    GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions
                                    ).Any();
                            }
                            foreach (IType constraintType in tp.Constraints)
                            {
                                IType c = newParameterizedType.SubstituteInType(constraintType);
                                ConstraintsValid &= conversions.IsConstraintConvertible(typeArg, c);
                            }
                        }
                    }
                }
                return(newType);
            }