'Build a PyMongo index spec from a MongoEngine index spec.'

@classmethod
def _build_index_spec(cls, spec):

    if isinstance(spec, six.string_types):
        spec = {'fields': [spec]}
    elif isinstance(spec, (list, tuple)):
        spec = {'fields': list(spec)}
    elif isinstance(spec, dict):
        spec = dict(spec)
    index_list = []
    direction = None
    allow_inheritance = cls._meta.get('allow_inheritance')
    include_cls = (allow_inheritance and (not spec.get('sparse', False)) and spec.get('cls', True) and ('_cls' not in spec['fields']))
    include_cls = (include_cls and (spec.get('cls', False) or cls._meta.get('index_cls', True)))
    if ('cls' in spec):
        spec.pop('cls')
    for key in spec['fields']:
        if isinstance(key, (list, tuple)):
            continue
        direction = pymongo.ASCENDING
        if key.startswith('-'):
            direction = pymongo.DESCENDING
        elif key.startswith('$'):
            direction = pymongo.TEXT
        elif key.startswith('#'):
            direction = pymongo.HASHED
        elif key.startswith('('):
            direction = pymongo.GEOSPHERE
        elif key.startswith(')'):
            direction = pymongo.GEOHAYSTACK
        elif key.startswith('*'):
            direction = pymongo.GEO2D
        if key.startswith(('+', '-', '*', '$', '#', '(', ')')):
            key = key[1:]
        parts = key.split('.')
        if (parts in (['pk'], ['id'], ['_id'])):
            key = '_id'
        else:
            fields = cls._lookup_field(parts)
            parts = []
            for field in fields:
                try:
                    if (field != '_id'):
                        field = field.db_field
                except AttributeError:
                    pass
                parts.append(field)
            key = '.'.join(parts)
        index_list.append((key, direction))
    if (include_cls and (direction not in (pymongo.GEO2D, pymongo.GEOHAYSTACK, pymongo.GEOSPHERE))):
        index_list.insert(0, ('_cls', 1))
    if index_list:
        spec['fields'] = index_list
    return spec
