public InfernalGenesisAbility0(GameState state) {
      super(
          state,
          "At the beginning of each player's upkeep, that player puts the top card of his or her library into his or her graveyard. Then he or she puts X 1/1 black Minion creature tokens onto the battlefield, where X is that card's converted mana cost.");

      this.addPattern(atTheBeginningOfEachPlayersUpkeep());
      SetGenerator thatPlayer =
          OwnerOf.instance(
              EventParameter.instance(
                  TriggerEvent.instance(This.instance()), EventType.Parameter.STEP));

      EventFactory mill =
          millCards(
              thatPlayer,
              1,
              "That player puts the top card of his or her library into his or her graveyard.");
      this.addEffect(mill);

      SetGenerator thatCard = NewObjectOf.instance(EffectResult.instance(mill));
      SetGenerator X = ConvertedManaCostOf.instance(thatCard);
      CreateTokensFactory f =
          new CreateTokensFactory(
              X,
              numberGenerator(1),
              numberGenerator(1),
              "Then he or she puts X 1/1 black Minion creature tokens onto the battlefield, where X is that card's converted mana cost.");
      f.setController(thatPlayer);
      f.setColors(Color.BLACK);
      f.setSubTypes(SubType.MINION);
      this.addEffect(f.getEventFactory());
    }
  public SurgicalExtraction(GameState state) {
    super(state);

    // Choose target card in a graveyard other than a basic land card.
    SetGenerator inGraveyards = InZone.instance(GraveyardOf.instance(Players.instance()));
    SetGenerator basicLands =
        Intersect.instance(HasSuperType.instance(SuperType.BASIC), HasType.instance(Type.LAND));
    SetGenerator legalTargets = RelativeComplement.instance(inGraveyards, basicLands);
    Target t =
        this.addTarget(legalTargets, "target card in a graveyard other than a basic land card");

    // Search its owner's graveyard, hand, and library for all cards with
    // the same name as that card and exile them.
    SetGenerator itsOwner = OwnerOf.instance(targetedBy(t));
    SetGenerator graveyard = GraveyardOf.instance(itsOwner);
    SetGenerator hand = HandOf.instance(itsOwner);
    SetGenerator library = LibraryOf.instance(itsOwner);
    SetGenerator zones = Union.instance(graveyard, hand, library);

    EventFactory effect =
        new EventFactory(
            EventType.SEARCH_FOR_ALL_AND_PUT_INTO,
            "Choose target card in a graveyard other than a basic land card. Search its owner's graveyard, hand, and library for all cards with the same name as that card and exile them.");
    effect.parameters.put(EventType.Parameter.CAUSE, This.instance());
    effect.parameters.put(EventType.Parameter.PLAYER, You.instance());
    effect.parameters.put(EventType.Parameter.ZONE, zones);
    effect.parameters.put(
        EventType.Parameter.TYPE,
        Identity.instance(HasName.instance(NameOf.instance(targetedBy(t)))));
    effect.parameters.put(EventType.Parameter.TO, ExileZone.instance());
    this.addEffect(effect);

    // Then that player shuffles his or her library.
    this.addEffect(shuffleLibrary(targetedBy(t), "Then that player shuffles his or her library."));
  }
    public SheoldredWhisperingOneAbility2(GameState state) {
      super(
          state, "At the beginning of each opponent's upkeep, that player sacrifices a creature.");
      this.addPattern(atTheBeginningOfEachOpponentsUpkeeps());

      SetGenerator thatPlayer = OwnerOf.instance(CurrentStep.instance());
      this.addEffect(
          sacrifice(
              thatPlayer, 1, CreaturePermanents.instance(), "That player sacrifices a creature."));
    }
    public TidehollowScullerAbility1(GameState state) {
      super(
          state,
          "When Tidehollow Sculler leaves the battlefield, return the exiled card to its owner's hand.");
      this.addPattern(whenThisLeavesTheBattlefield());

      this.getLinkManager().addLinkClass(TidehollowScullerAbility0.class);
      SetGenerator exiledCard = ChosenFor.instance(LinkedTo.instance(This.instance()));

      EventFactory move =
          new EventFactory(EventType.MOVE_OBJECTS, "Return the exiled card to its owner's hand.");
      move.parameters.put(EventType.Parameter.CAUSE, This.instance());
      move.parameters.put(EventType.Parameter.TO, HandOf.instance(OwnerOf.instance(exiledCard)));
      move.parameters.put(EventType.Parameter.OBJECT, exiledCard);
      this.addEffect(move);
    }
    public DamageTrigger(GameState state) {
      super(
          state,
          "At the beginning of each opponent's upkeep, if that player has two or fewer cards in hand, Hellfire Mongrel deals 2 damage to him or her.");
      this.addPattern(atTheBeginningOfEachOpponentsUpkeeps());

      SetGenerator twoOrFewer = Between.instance(null, 2);
      SetGenerator upkeep =
          EventParameter.instance(TriggerEvent.instance(This.instance()), EventType.Parameter.STEP);
      SetGenerator thatPlayer = OwnerOf.instance(upkeep);
      SetGenerator cardsInHand = Count.instance(InZone.instance(HandOf.instance(thatPlayer)));
      this.interveningIf = Intersect.instance(twoOrFewer, cardsInHand);

      this.addEffect(
          permanentDealDamage(2, thatPlayer, "Hellfire Mongrel deals 2 damage to that player."));
    }
  public GraspofPhantoms(GameState state) {
    super(state);

    // Put target creature on top of its owner's library.
    SetGenerator target =
        targetedBy(this.addTarget(CreaturePermanents.instance(), "target creature"));
    EventFactory put =
        new EventFactory(
            EventType.MOVE_OBJECTS, "Put target creature on top of its owner's library.");
    put.parameters.put(EventType.Parameter.CAUSE, This.instance());
    put.parameters.put(EventType.Parameter.TO, LibraryOf.instance(OwnerOf.instance(target)));
    put.parameters.put(EventType.Parameter.OBJECT, target);
    this.addEffect(put);

    // Flashback (7)(U) (You may cast this card from your graveyard for its
    // flashback cost. Then exile it.)
    this.addAbility(new org.rnd.jmagic.abilities.keywords.Flashback(state, "(7)(U)"));
  }
    public TheLordGivethBack(GameState state) {
      super(
          state,
          "When Journey to Nowhere leaves the battlefield, return the exiled card to the battlefield under its owner's control.");
      this.addPattern(whenThisLeavesTheBattlefield());

      SetGenerator exiledCard = ChosenFor.instance(LinkedTo.instance(This.instance()));

      EventFactory returnCard =
          new EventFactory(
              EventType.PUT_ONTO_BATTLEFIELD,
              "Return the exiled card to the battlefield under its owner's control.");
      returnCard.parameters.put(EventType.Parameter.CAUSE, This.instance());
      returnCard.parameters.put(EventType.Parameter.CONTROLLER, OwnerOf.instance(exiledCard));
      returnCard.parameters.put(EventType.Parameter.OBJECT, exiledCard);
      this.addEffect(returnCard);

      this.getLinkManager().addLinkClass(TheLordTakethAway.class);
    }
  public DarkConfidantAbility(GameState state) {
    super(
        state,
        "At the beginning of your upkeep, reveal the top card of your library and put that card into your hand. You lose life equal to its converted mana cost.");
    this.addPattern(atTheBeginningOfYourUpkeep());

    SetGenerator library = LibraryOf.instance(You.instance());
    SetGenerator topCard = TopCards.instance(numberGenerator(1), library);

    EventFactory reveal = reveal(topCard, "Reveal the top card of your library");
    this.addEffect(reveal);
    this.addEffect(
        putIntoHand(topCard, OwnerOf.instance(topCard), "and put that card into your hand."));
    this.addEffect(
        loseLife(
            You.instance(),
            ConvertedManaCostOf.instance(EffectResult.instance(reveal)),
            "You lose life equal to its converted mana cost."));
  }