private String doStackDescription(SpellAbility sa) {

        int finalPower = AbilityFactory.calculateAmount(AF.getHostCard(), tokenPower, sa);

        int finalToughness = AbilityFactory.calculateAmount(AF.getHostCard(), tokenToughness, sa);

        int finalAmount = AbilityFactory.calculateAmount(AF.getHostCard(), tokenAmount, sa);

        StringBuilder sb = new StringBuilder();

        if (sa instanceof Ability_Sub)
            sb.append(" ");
        else
            sb.append(AF.getHostCard().getName()).append(" - ");

        sb.append("Put (").append(finalAmount).append(") ").append(finalPower).append("/").append(finalToughness);
        sb.append(" ").append(tokenName).append(" token");
        if (finalAmount != 1) sb.append("s");
        sb.append(" onto the battlefield");

        if (tokenOwner.equals("Opponent")) {
            sb.append(" under your opponent's control.");
        } else {
            sb.append(".");
        }

        if (sa.getSubAbility() != null) {
            sb.append(sa.getSubAbility().getStackDescription());
        }

        return sb.toString();
    }