return typecode or substitute type for wildcard or
    derived type.  For serialization only.

def _get_type_or_substitute(typecode, pyobj, sw, elt):
    '''return typecode or substitute type for wildcard or
    derived type.  For serialization only.
    '''
    sub = getattr(pyobj, 'typecode', typecode)
    if sub is typecode or sub is None:
        return typecode

    # Element WildCard
    if isinstance(typecode, AnyElement):
        return sub
 
    # Global Element Declaration
    if isinstance(sub, ElementDeclaration):
        if (typecode.nspname,typecode.pname) == (sub.nspname,sub.pname):
            raise TypeError(\
                'bad usage, failed to serialize element reference (%s, %s), in: %s' %
                 (typecode.nspname, typecode.pname, sw.Backtrace(elt),))

        # check substitutionGroup 
        if _is_substitute_element(typecode, sub):
            return sub

        raise TypeError(\
            'failed to serialize (%s, %s) illegal sub GED (%s,%s): %s' %
             (typecode.nspname, typecode.pname, sub.nspname, sub.pname,
              sw.Backtrace(elt),))

    # Local Element
    if not isinstance(typecode, AnyType) and not isinstance(sub, typecode.__class__):
        raise TypeError(\
            'failed to serialize substitute %s for %s,  not derivation: %s' %
             (sub, typecode, sw.Backtrace(elt),))

    # Make our substitution type match the elements facets,
    # since typecode is created for a single existing pyobj
    # some facets are irrelevant.
    sub = _copy(sub)
    sub.nspname = typecode.nspname
    sub.pname = typecode.pname
    sub.aname = typecode.aname
    sub.minOccurs = sub.maxOccurs = 1
    return sub