private static ITypeName GetName(this ITypeElement typeElem,
                                         ISubstitution substitution,
                                         IDictionary <DeclaredElementInstance, IName> seenElems)
        {
            if (typeElem == null)
            {
                return(Names.UnknownType);
            }

            var name = typeElem.GetSimplePredefinedType() ??
                       IfElementIs <IDelegate>(typeElem, GetName, substitution, seenElems, Names.UnknownDelegateType) ??
                       IfElementIs <IEnum>(typeElem, GetName, substitution, seenElems, Names.UnknownType) ??
                       IfElementIs <IInterface>(typeElem, GetName, substitution, seenElems, Names.UnknownType) ??
                       IfElementIs <IStruct>(typeElem, GetName, substitution, seenElems, Names.UnknownType) ??
                       Names.Type(typeElem.GetAssemblyQualifiedName(substitution, seenElems));

            var dei = new DeclaredElementInstance(typeElem, substitution);

            seenElems[dei] = name;
            return(name);
        }