'This function reallocates widthes between columns.
:param shift is array which contain lack or plenty of space in the column.
Lack of space happens when a longest word in a column does not fit into originally allocated space.
This function acts as Robin Hood: it takes excess of space from the "richest" column and gives it
to the poorest ones.'

def _justify(self):

    minLengths = [max([max(map(len, (row[i].split() + ['']))) for row in self._rows if (len(row) > 0)]) for i in range(self._colsNum)]
    shifts = [(w - mw) for (mw, w) in zip(minLengths, self._widthes)]
    borrow = zip(self._colsRange, shifts)
    borrow.sort((lambda a, b: cmp(a[1], b[1])))
    delta = ([0] * self._colsNum)
    donorIdx = (self._colsNum - 1)
    recIdx = 0
    while True:
        curDonation = borrow[donorIdx][1]
        curRec = borrow[recIdx][1]
        if ((curRec >= 0) or (curDonation <= 0)):
            break
        curDelta = min(curDonation, (- curRec))
        curDonation -= curDelta
        curRec += curDelta
        delta[borrow[donorIdx][0]] -= curDelta
        delta[borrow[recIdx][0]] += curDelta
        if (curDonation == 0):
            donorIdx -= 1
        if (curRec == 0):
            recIdx += 1
    for i in self._colsRange:
        self._widthes[i] += delta[i]
