def do_army_edition(self, army=None, special_message=''):
        army = Army.get_by_id(self.request.matchdict.get('id'))

        if 'unit_to_remove[]' in self.request.POST:
            for dice_id in self.request.POST.getall('unit_to_remove[]'):
                Dice.get_by_id(int(dice_id)).delete()
        #Ugly, but how to do otherwise ?
        regexp = re.compile('unit_amount_([1-9][0-9]{0,2})')
        for element, amount in self.request.POST.items():
            m = regexp.search(element)
            if ((m != None) and (int(amount) > 0)):
                for i in range(int(amount)):
                    dice = Dice(DiceTemplate.get_by_id(m.group(1)), army)
                    dice.save()

        return self.army_edition(army, ('army %s succesfully modified !' % army.name))
    def save_action(self):
        action = SaveAction.get_by_id(self.request.matchdict.get('id'))
        damage = action.damage
        army = action.army
        army.set_roll_type(SaveMeleeRoll())

        #Step 0 : nothing done. Let's roll the army.
        if action.step == 0:
            army.roll(SaveMeleeRoll())
            action.step = 1

        #Step 1 : check if some effect can be resolved. Else go to step 2.
        if action.step == 1:
            #For now, automatically assume that everything is fine
            action.step = 2

        #Step 2 : require that enough unit are taken as casualty
        if action.step == 2:
            saves = army.get_save_result()
            min_health = 4
            if damage < saves:
                remaining = 0
            else:
                remaining = damage - saves

            #We beed to know what is the smallest unit (in health) in the army
            for unit in army.components:
                if unit.health < min_health:
                    min_health = unit.health

            #if damage cannot kill any dice, it's discarded
            if remaining < min_health:
                action.step = 3
                casualty = []
            elif 'unit_to_kill[]' in self.request.POST:
                casualty = []
                sum_health = 0
                for dice_id in self.request.POST.getall('unit_to_kill[]'):
                    unit = Dice.get_by_id(int(dice_id))
                    if not(unit in army.components):
                        raise RuntimeError('Trying to kill an unit outside of the army !')
                    casualty.append(unit)
                    sum_health += unit.health

                if (sum_health <= remaining) and (min_health > (remaining - sum_health)):
                    #It's a valid casualty removal
                    action.step = 3
                    

        if action.step == 3:
            #Prepare the view before altering the result.
            results = []
            for dice in army.components:
                list_icon = []
                list_desc = []
                for face in dice.active_faces:
                    list_icon.append(face.picture)
                    list_desc.append(face.name)
                results.append((dice.name, list_icon, list_desc))
            dead_army = army.owner.dead_army

            #We remove the casualty now
            for unit in casualty:
                unit.army = dead_army

            dice_list = [(dice.name, dice.template.picture) for dice in army.components]
            dead_dice_list = [(dice.name, dice.template.picture) for dice in casualty]
            action.delete(explicit=True)
        else:
            action.save()

        #Now, dispatch to the good view
        if action.step == 1:
            #resolve SAI
            url = self.request.route_url('save_action_step_one', id=action.id)
            return_value = HTTPFound(location=url)
        elif action.step == 2:
            #remove casualties
            url = self.request.route_url('save_action_step_two', id=action.id)
            return_value = HTTPFound(location=url)
        else:
            #save finished
            #We do the view without redirection to avoid having to store silly thing.
            return_value = {'results': results, 'dices': dice_list, 'dead_dices': dead_dice_list, 'save': saves, 'damage': damage, 'remaining': remaining, 'route_next_step': self.request.route_url('army_selection')}
        return return_value