def finish_level(self):
        """
            This method does postprocessing of the current
            optimization level after it is solved. This includes
            *hardening* some of the soft clauses (depending on their
            remaining weights) and also garbage collection.
        """

        # assumptions to remove
        self.garbage = set()

        # sum of weights of the remaining levels
        sumw = sum([w * len(self.wstr[w]) for w in self.blop[(self.levl + 1):]])

        # trying to harden selectors and sums
        for s in self.sels + self.sums:
            if self.wght[s] > sumw:
                self.oracle.add_clause([s])
                self.garbage.add(s)

        if self.verbose > 1:
            print('c hardened:', len(self.garbage))

        # remove unnecessary assumptions
        self.filter_assumps()