def concat(invises, outvis, timesort=False):
    tb = util.tools.table()
    ms = util.tools.ms()
    if os.path.exists(outvis):
        raise RuntimeError('output "%s" already exists' % outvis)
    for invis in invises:
        if not os.path.isdir(invis):
            raise RuntimeError('input "%s" does not exist' % invis)
    tb.open(b(invises[0]))
    tb.copy(b(outvis), deep=True, valuecopy=True)
    tb.close()
    ms.open(b(outvis), nomodify=False)
    for invis in invises[1:]:
        ms.concatenate(msfile=b(invis), freqtol=b(concat_freqtol),
                        dirtol=b(concat_dirtol))
    ms.writehistory(message=b'taskname=tasklib.concat', origin=b'tasklib.concat')
    ms.writehistory(message=b('vis = ' + ', '.join(invises)), origin=b'tasklib.concat')
    ms.writehistory(message=b('timesort = ' + 'FT'[int(timesort)]), origin=b'tasklib.concat')
    if timesort:
        ms.timesort()
    ms.close()