public static Input input_tapXCost(final int nCards, final String cardType, final CardList cardList, SpellAbility sa, final Cost_Payment payment) {
        //final SpellAbility sp = sa;
        Input target = new Input() {

            private static final long serialVersionUID = 6438988130447851042L;
            int nTapped = 0;

            @Override
            public void showMessage() {
                if (cardList.size() == 0) stop();

                int left = nCards - nTapped;
                AllZone.getDisplay().showMessage("Select a " + cardType + " to tap (" + left + " left)");
                ButtonUtil.enableOnlyCancel();
            }

            @Override
            public void selectButtonCancel() {
                cancel();
            }

            @Override
            public void selectCard(Card card, PlayerZone zone) {
                if (zone.is(Constant.Zone.Battlefield) && cardList.contains(card) && card.isUntapped()) {
                    // send in CardList for Typing
                    card.tap();
                    payment.addPayTapXTypeTappedList(card);
                    cardList.remove(card);
                    payment.getAbility().addCostToHashList(card, "Tapped");
                    nTapped++;

                    if (nTapped == nCards)
                        done();
                    else if (cardList.size() == 0)    // this really shouldn't happen
                        cancel();
                    else
                        showMessage();
                }
            }

            public void cancel() {
                payment.setCancel(true);
                stop();
                payment.payCost();
            }

            public void done() {
                payment.setPayTapXType(true);
                stop();
                payment.payCost();
            }
        };

        return target;
    }//input_tapXCost()