def get_equivalent_positions(block):
    consensus = block['sequences'][0]['seq']
    rest = block['sequences'][1:]
    if '-' in consensus or '.' in consensus:
        raise ValueError("First sequence (consensus?) contains gaps")
    seen = set()
    dupes = set()
    for rec in rest:
        if rec['id'] in seen:
            dupes.add(rec['id'])
        else:
            seen.add(rec['id'])
    if dupes:
        raise ValueError("Duplicate sequences:\n" + '\n'.join(dupes))
    curr_shift = {}
    curr_resn = {}
    for rec in rest:
        curr_shift[rec['id']] = 0
        curr_resn[rec['id']] = rec['head_len']
    equivalencies = dict((i+1, {}) for i in xrange(len(consensus)))
    for i, char in enumerate(consensus):
        assert char.isupper()
        for rec in rest:
            rid = rec['id']
            strposn = i + curr_shift[rid]
            if rec['seq'][strposn].isupper():
                curr_resn[rid] += 1
            elif rec['seq'][strposn].islower():
                while rec['seq'][strposn].islower():
                    curr_shift[rid] += 1
                    curr_resn[rid] += 1
                    strposn += 1
                curr_resn[rid] += 1
            else:
                assert rec['seq'][strposn] in '.-'
                continue
            equivalencies[i+1][rid] = curr_resn[rid]
    return equivalencies