Apply the given outcomes to this rule.

        If user intervention is required, outcomes are not applied
        unless a ui.UI is supplied.

def apply_outcomes(self, outcomes, uio, dropped=False, prevxn=None):
        """Apply the given outcomes to this rule.

        If user intervention is required, outcomes are not applied
        unless a ui.UI is supplied.
        """
        if self.dropped and not dropped:
            # do nothing for dropped xn, unless specifically told to
            return

        if 'drop' in outcomes:
            highscore = score.score(outcomes['drop'].highest()[0])
            if highscore >= threshold['y']:
                # drop without prompting
                self.dropped = True
            elif highscore < threshold['n?']:
                # do NOT drop, and don't even ask
                pass
            else:
                uio.show('DROP was determined for transaction:')
                uio.show('')
                uio.show(self.summary())
                if highscore >= threshold['y?']:
                    default = True
                elif highscore >= threshold['?']:
                    default = None
                else:
                    default = False
                try:
                    self.dropped = uio.yn('DROP this transaction?', default)
                except ui.RejectWarning:
                    # we assume they mean "no"
                    pass

        if self.dropped and not dropped:
            # do nothing further for dropped xn, unless specifically told to
            return

        # rebate outcomes
        #
        # A rebate is a rebate of the previous transaction.
        # The proportions of credits in the prev xn are kept,
        # inverted (i.e. made debits) and scaled to the rebate
        # amount credit amount.
        if 'rebate' in outcomes and not self.src and prevxn is not None:
            ratio = self.amount / prevxn.amount
            def scale(dst_ep):
                amount = (dst_ep.amount * ratio).quantize(dst_ep.amount)
                return Endpoint(dst_ep.account, -amount)
            self.src = map(scale, prevxn.dst)
            # handle rounding errors
            self.src[0].amount -= self.amount + sum(x.amount for x in self.src)

        # account outcomes
        for outcome in ['src', 'dst']:
            if outcome not in outcomes or getattr(self, outcome):
                # no outcome, or the attribute was already set
                continue

            endpoints = []
            highest = outcomes[outcome].highest()
            try:
                highscore = score.score(highest[0])
                if len(highest) == 1:
                    if highscore >= threshold['y']:
                        # do it
                        endpoints = [
                            Endpoint(score.value(highest[0]), self.amount)
                        ]
                    else:
                        uio.show('Choose ' + outcome + ' for transaction:')
                        uio.show('')
                        uio.show(self.summary())

                        prompt = 'Is the account {0}?'.format(
                            score.value(highest[0])
                        )
                        if highscore >= threshold['y?']:
                            default = True
                        elif highscore >= threshold['?']:
                            default = None
                        else:
                            default = False
                        if uio.yn(prompt, default):
                            endpoints = [
                                Endpoint(
                                    score.value(highest[0]),
                                    self.amount
                                )
                            ]
                        else:
                            raise ui.RejectWarning('top score declined')
                else:
                    # tied highest score, let user pick
                    uio.show('Choose ' + outcome + ' for transaction:')
                    uio.show('')
                    uio.show(self.summary())

                    prompt = 'Choose an account'
                    endpoints = [
                        Endpoint(
                            uio.choose(prompt, map(score.value, highest)),
                            self.amount
                        )
                    ]

            except ui.RejectWarning:
                # user has rejected our offer(s)
                uio.show("\n")
                uio.show('Enter ' + outcome + ' endpoints:')
                try:
                    endpoints = []
                    remaining = self.amount
                    while remaining:
                        uio.show('\n${0} remaining'.format(remaining))
                        account = uio.text(
                            ' Enter account',
                            score.value(highest[0]) if highest else None
                        )
                        amount = uio.decimal(
                            ' Enter amount',
                            default=remaining,
                            lower=0,
                            upper=remaining
                        )
                        endpoints.append(Endpoint(account, amount))
                        remaining = self.amount \
                            - sum(map(lambda x: x.amount, endpoints))
                except ui.RejectWarning:
                    # bail out
                    sys.exit("bye!")

            # flip amounts if it was a src outcome
            if outcome == 'src':
                endpoints = map(
                    lambda x: Endpoint(x.account, -x.amount),
                    endpoints
                )

            # set endpoints
            setattr(self, outcome, endpoints)