Inefficient comparison of src and dest dicts.
        Recurses through dict and lists.
        returns (is_identical, modifications, additions, deletions)
        where each
            is_identical is a boolean True if the dicts have
                contents that compare equal.
        and the other three are dicts:
            attributes both, but with different values
            attributes in dest but not in src
            attributes in src but not in dest

        Returned dicts may alias objects in src, and dest

def create(src, dest, **kwargs):
        """Inefficient comparison of src and dest dicts.
        Recurses through dict and lists.
        returns (is_identical, modifications, additions, deletions)
        where each
            is_identical is a boolean True if the dicts have
                contents that compare equal.
        and the other three are dicts:
            attributes both, but with different values
            attributes in dest but not in src
            attributes in src but not in dest

        Returned dicts may alias objects in src, and dest
        """
        if src == dest:
            return None
        trivial_order = [(i, i) for i in range(min(len(src), len(dest)))]
        optimal_order = trivial_order
        src_ind = 0
        dest_ind = 0
        add_offset = 0
        num_deletions = 0
        diffs = ListDiff()
        for p in optimal_order:
            ns, nd = p
            while src_ind < ns:
                diffs.add_deletion(src_ind, src[src_ind])
                src_ind += 1
                num_deletions += 1
            while dest_ind < nd:
                diffs.add_insertion(src_ind - num_deletions, add_offset, dest[dest_ind])
                dest_ind += 1
                add_offset += 1
            sv, dv = src[ns], dest[nd]
            if sv != dv:
                rec_call = None
                if isinstance(sv, dict) and isinstance(dv, dict):
                    rec_call = DictDiff.create(sv, dv, **kwargs)
                elif isinstance(sv, list) and isinstance(dv, list):
                    rec_call = ListDiff.create(sv, dv, **kwargs)
                elif kwargs.get('wrap_dict_in_list', False):
                    if isinstance(sv, dict) and isinstance(dv, list):
                        rec_call = ListDiff.create([sv], dv, **kwargs)
                    elif isinstance(dv, dict) or isinstance(sv, list):
                        rec_call = ListDiff.create(sv, [dv], **kwargs)
                if rec_call is not None:
                    diffs.add_modificaton(src_ind, rec_call)
                else:
                    diffs.add_modificaton(src_ind, (sv, dv))
            src_ind += 1
            dest_ind += 1
        while src_ind < len(src):
            diffs.add_deletion(src_ind, src[src_ind])
            src_ind += 1
        while dest_ind < len(dest):
            diffs.add_insertion(src_ind, add_offset, dest[dest_ind])
            dest_ind += 1
            add_offset += 1
        diffs.finish()
        return diffs