@Override
  public PaymentDecision visit(CostReveal cost) {

    final String type = cost.getType();
    List<Card> hand = new ArrayList<Card>(player.getCardsIn(ZoneType.Hand));

    if (cost.payCostFromSource()) {
      if (!hand.contains(source)) {
        return null;
      }
      return PaymentDecision.card(source);
    }

    if (cost.getType().equals("Hand"))
      return PaymentDecision.card(player.getCardsIn(ZoneType.Hand));

    if (cost.getType().equals("SameColor")) {
      return null;
    }

    hand = CardLists.getValidCards(hand, type.split(";"), player, source);
    Integer c = cost.convertAmount();
    if (c == null) {
      final String sVar = ability.getSVar(cost.getAmount());
      if (sVar.equals("XChoice")) {
        c = hand.size();
      } else {
        c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
      }
    }

    final AiController aic = ((PlayerControllerAi) player.getController()).getAi();
    return PaymentDecision.card(aic.getCardsToDiscard(c, type.split(";"), ability));
  }
  @Override
  public PaymentDecision visit(CostDiscard cost) {
    final String type = cost.getType();

    final List<Card> hand = player.getCardsIn(ZoneType.Hand);
    if (type.equals("LastDrawn")) {
      if (!hand.contains(player.getLastDrawnCard())) {
        return null;
      }
      return PaymentDecision.card(player.getLastDrawnCard());
    } else if (cost.payCostFromSource()) {
      if (!hand.contains(source)) {
        return null;
      }

      return PaymentDecision.card(source);
    } else if (type.equals("Hand")) {
      return PaymentDecision.card(hand);
    }

    if (type.contains("WithSameName")) {
      return null;
    }
    Integer c = cost.convertAmount();
    if (c == null) {
      final String sVar = ability.getSVar(cost.getAmount());
      if (sVar.equals("XChoice")) {
        return null;
      }
      c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
    }

    if (type.equals("Random")) {
      return PaymentDecision.card(CardLists.getRandomSubList(hand, c));
    } else {
      final AiController aic = ((PlayerControllerAi) player.getController()).getAi();
      return PaymentDecision.card(aic.getCardsToDiscard(c, type.split(";"), ability));
    }
  }