def MI_parse_args(self, args, ingore_index2=False, allow_new=False):
    '''
    Parse the arguments for indexing in MIDict.

    Full syntax: ``d[index1:key, index2]``.

    ``index2`` can be flexible indexing (int, list, slice etc.) as in ``IndexDict``.

    Short syntax:

    * d[key] <==> d[key,] <==> d[first_index:key, all_indice_except_first]
    * d[:key] <==> d[:key,] <==> d[None:key] <==> d[last_index:key, all_indice_except_last]
    * d[key, index2] <==> d[first_index:key, index2] # this is valid
      # only when index2 is a list or slice object
    * d[index1:key, index2_1, index2_2, ...] <==> d[index1:key, (index2_1, index2_2, ...)]

    '''
    empty = len(self.indices) == 0
    if empty and not allow_new:
        raise KeyError('Item not found (dictionary is empty): %s' % (args,))

    names = force_list(self.indices.keys())

    Nargs = len(args) if isinstance(args, tuple) else 1

    _default = object()
    index1 = index2 = _default

    if isinstance(args, tuple):
        # easy handle of default logic (use continue/break as shortcut)
        for _ in (1,):
            if ingore_index2:
                continue

            if isinstance(args[0], slice):
                index1, key = args[0].start, args[0].stop

                if Nargs == 2:
                    index2 = args[1]
                elif Nargs > 2:
                    index2 = args[1:]
                break

            # args[0] is not a slice
            if Nargs > 1 and isinstance(args[1], (list, slice)):
                if Nargs == 2:
                    key, index2 = args
                    break
                else:
                    raise KeyError('No arguments allowed after index2, found: %s' % (args[2:],))
        else:
            key = args

    elif isinstance(args, slice):
        index1, key = args.start, args.stop

    else:
        key = args

    if empty: # allow_new is True
        index1_last = False

        exist_names = []  # list of names already passed in as arguments
        if index1 is not _default:
            if index1 is None: # slice syntax d[:key]
                index1_last = True
                index1 = _default
            elif isinstance(index1, int):
                raise TypeError('Index1 can not be int when dictionary '
                                'is empty: %s' % (index1,))
            else:
                MI_check_index_name(index1)
                exist_names.append(index1)
        if index2 is not _default:
            if isinstance(index2, (tuple, list)):
                map(MI_check_index_name, index2)
                exist_names.extend(index2)
            elif isinstance(index2, (int, slice)):
                raise TypeError('Index2 can not be int or slice when '
                                'dictionary is empty: %s' % (index2,))
            else:
                MI_check_index_name(index2)
                exist_names.append(index2)

        # auto generate index names and avoid conficts with existing names
        if index1 is _default:
            if index1_last:
                if len(exist_names) > 1: # index2 is specified
                    name1 = 'index_%s' % (len(exist_names) + 1)
                else:
                    name1 = 'index_2'
            else:
                name1 = 'index_1'
            index1 = get_unique_name(name1, exist_names)
            exist_names.append(index1)

        if index2 is _default:
            name2 = 'index_1' if index1_last else 'index_2'
            index2 = get_unique_name(name2, exist_names)

        return index1, key, index2, index1_last

    # not empty:

    if index1 is _default:  # not specified
        index1 = 0
    elif index1 is None:  # slice syntax d[:key]
        index1 = -1

    # index1 is always returned as an int
    index1 = _key_to_index_single(names, index1)

    try:
        item = MI_get_item(self, key, index1)
    except KeyError:
        if allow_new:  # new key for setitem; item_d = None
            item = None
        else:
            raise KeyError('Key not found in index #%s "%s": %s' %
                            (index1, names[index1], key))

    if ingore_index2:  # used by delitem
        return item

    if index2 is _default:  # not specified
        # index2 defaults to all indices except index1
        if len(names) == 1:
            index2 = 0  # index2 defaults to the only one index
        else:
            index2 = force_list(range(len(names)))
            index2.remove(index1)
            if len(index2) == 1:  # single index
                index2 = index2[0]
    else:
        # index2 is always returned as int or list of int
        index2 = _key_to_index(names, index2)

    if item is None:  # allow_new. item and value are None
        return index1, key, index2, None, None

#    try:
#        value = mget_list(item, index2)
#    except IndexError:
#        raise KeyError('Index not found: %s' % (index2,))

    # no need to try since index2 is always returned as int or list of int
    value = mget_list(item, index2)
    return index1, key, index2, item, value