def analyze(self, chunkSize, *sinks):
        """  Figure out the best diffs to use to reach all our required volumes. """
        measureSize = False
        if self.measureSize:
            for sink in sinks:
                if sink.isRemote:
                    measureSize = True

        # Use destination (already uploaded) edges first
        sinks = list(sinks)
        sinks.reverse()
        self.dest = sinks[0]

        def currentSize():
            return sum([
                n.diffSize
                for n in self.nodes.values()
                if n.diff is not None and n.diff.sink != self.dest
            ])

        while True:
            self._analyzeDontMeasure(chunkSize, measureSize, *sinks)

            if not measureSize:
                return

            estimatedSize = currentSize()

            # logger.info("Measuring any estimated diffs")

            for node in self.nodes.values():
                edge = node.diff
                if edge is not None and edge.sink != self.dest and edge.sizeIsEstimated:
                    edge.sink.measureSize(edge, chunkSize)

            actualSize = currentSize()

            logger.info(
                "measured size (%s), estimated size (%s)",
                humanize(actualSize), humanize(estimatedSize),
            )

            if actualSize <= 1.2 * estimatedSize:
                return