Synchronise subtitles using a given list of SyncPoints.

def sync(self, syncPointList):
        """Synchronise subtitles using a given list of SyncPoints."""

        if len(syncPointList) == 0:
            return

        subsCopy = self._subs.clone()

        syncPointList.sort()

        SubAssert(syncPointList[0].subNo >= 0)
        SubAssert(syncPointList[0].subNo < subsCopy.size())
        SubAssert(syncPointList[-1].subNo < subsCopy.size())

        # Always start from the first subtitle.
        firstSyncPoint = self._getLowestSyncPoint(syncPointList, subsCopy)
        if firstSyncPoint != syncPointList[0]:
            syncPointList.insert(0, firstSyncPoint)

        for i, syncPoint in enumerate(syncPointList):

            # Algorithm:
            # 1. Calculate time deltas between sync points and between subs:
            #        DE_OLD = subTime[secondSyncSubNo] - subTime[firstSyncSubNo]
            #        DE_NEW = secondSyncTime - firstSyncTime
            # 2. Calculate proportional sub position within DE_OLD:
            #        d = (subTime - subTime[firstSubNo]) / DE_OLD
            # 3. "d" is constant within deltas, so we can now calculate newSubTime:
            #        newSubTime = DE_NEW * d + firstSyncTime

            firstSyncPoint = syncPointList[i]
            secondSyncPoint = self._getSyncPointOrEnd(i + 1, syncPointList, subsCopy)

            log.debug(_("Syncing times for sync points:"))
            log.debug("  %s" % firstSyncPoint)
            log.debug("  %s" % secondSyncPoint)

            # A case for the last one syncPoint
            if firstSyncPoint == secondSyncPoint:
                continue

            secondSubNo = secondSyncPoint.subNo
            firstSubNo = firstSyncPoint.subNo

            firstOldSub = subsCopy[firstSubNo]
            secondOldSub = subsCopy[secondSubNo]

            oldStartDelta, oldEndDelta = self._getDeltas(firstOldSub, secondOldSub)
            newStartDelta, newEndDelta = self._getDeltas(firstSyncPoint, secondSyncPoint)

            for subNo in range(firstSubNo, secondSubNo + 1):
                sub = subsCopy[subNo]
                newStartTime = self._calculateTime(sub.start, firstOldSub.start,
                    firstSyncPoint.start, oldStartDelta, newStartDelta)
                newEndTime = self._calculateTime(sub.end, firstOldSub.end,
                    firstSyncPoint.end, oldEndDelta, newEndDelta)

                self._subs.changeSubStart(subNo, newStartTime)
                self._subs.changeSubEnd(subNo, newEndTime)