nus-yam/ex-repair huggingface dataset:
Program: 158709
Project: 158709
Buggy source:
@Override public boolean moveCardToGraveyardWithInfo(Card card,UUID sourceId,Game game,Zone fromZone){
  boolean result=false;
  if (card.moveToZone(Zone.GRAVEYARD,sourceId,game,fromZone != null ? fromZone.equals(Zone.BATTLEFIELD) : false)) {
    if (!game.isSimulation()) {
      if (card instanceof PermanentCard) {
        card=game.getCard(card.getId());
      }
      StringBuilder sb=new StringBuilder(this.getLogName()).append("String_Node_Str").append(card.getLogName()).append("String_Node_Str").append(fromZone != null ? "String_Node_Str" + fromZone.toString().toLowerCase(Locale.ENGLISH) + "String_Node_Str" : "String_Node_Str");
      if (card.getOwnerId().equals(getId())) {
        sb.append("String_Node_Str");
      }
 else {
        sb.append("String_Node_Str");
      }
      game.informPlayers(sb.toString());
    }
    result=true;
  }
  return result;
}

Fixed version (ground truth):
@Override public boolean moveCardToGraveyardWithInfo(Card card,UUID sourceId,Game game,Zone fromZone){
  boolean result=false;
  if (card.moveToZone(Zone.GRAVEYARD,sourceId,game,fromZone != null ? fromZone.equals(Zone.BATTLEFIELD) : false)) {
    if (!game.isSimulation()) {
      if (card instanceof PermanentCard) {
        card=game.getCard(card.getId());
      }
      StringBuilder sb=new StringBuilder(this.getLogName()).append("String_Node_Str").append(card.getLogName()).append("String_Node_Str").append(card.isCopy() ? "String_Node_Str" : "String_Node_Str").append(fromZone != null ? "String_Node_Str" + fromZone.toString().toLowerCase(Locale.ENGLISH) + "String_Node_Str" : "String_Node_Str");
      if (card.getOwnerId().equals(getId())) {
        sb.append("String_Node_Str");
      }
 else {
        sb.append("String_Node_Str");
      }
      game.informPlayers(sb.toString());
    }
    result=true;
  }
  return result;
}
Program: 158710
Project: 158710
Buggy source:
/** 
 * Handle the blocker selection process
 * @param blockController player that controlls how to block, if null thedefender is the controller
 * @param game
 */
public void selectBlockers(Player blockController,Game game){
  Player attacker=game.getPlayer(attackerId);
  this.retrieveMustBlockAttackerRequirements(attacker,game);
  Player controller;
  for (  UUID defenderId : getPlayerDefenders(game)) {
    Player defender=game.getPlayer(defenderId);
    if (defender != null) {
      boolean choose=true;
      if (blockController == null) {
        controller=defender;
      }
 else {
        controller=blockController;
      }
      while (choose) {
        controller.selectBlockers(game,defenderId);
        if (game.isPaused() || game.gameOver(null) || game.executingRollback()) {
          return;
        }
        if (!this.checkBlockRestrictions(defender,game)) {
          if (controller.isHuman()) {
            continue;
          }
        }
        choose=!this.checkBlockRequirementsAfter(defender,controller,game);
        if (!choose) {
          choose=!this.checkBlockRestrictionsAfter(defender,controller,game);
        }
      }
      game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_BLOCKERS,defenderId,defenderId));
      if (!game.isSimulation()) {
        this.logBlockerInfo(defender,game);
      }
    }
  }
  TraceUtil.traceCombatIfNeeded(game,this);
}

Fixed version (ground truth):
/** 
 * Handle the blocker selection process
 * @param blockController player that controlls how to block, if null thedefender is the controller
 * @param game
 */
public void selectBlockers(Player blockController,Game game){
  Player attacker=game.getPlayer(attackerId);
  game.getCombat().retrieveMustBlockAttackerRequirements(attacker,game);
  Player controller;
  for (  UUID defenderId : getPlayerDefenders(game)) {
    Player defender=game.getPlayer(defenderId);
    if (defender != null) {
      boolean choose=true;
      if (blockController == null) {
        controller=defender;
      }
 else {
        controller=blockController;
      }
      while (choose) {
        controller.selectBlockers(game,defenderId);
        if (game.isPaused() || game.gameOver(null) || game.executingRollback()) {
          return;
        }
        if (!game.getCombat().checkBlockRestrictions(defender,game)) {
          if (controller.isHuman()) {
            continue;
          }
        }
        choose=!game.getCombat().checkBlockRequirementsAfter(defender,controller,game);
        if (!choose) {
          choose=!game.getCombat().checkBlockRestrictionsAfter(defender,controller,game);
        }
      }
      game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_BLOCKERS,defenderId,defenderId));
      if (!game.isSimulation()) {
        game.getCombat().logBlockerInfo(defender,game);
      }
    }
  }
  TraceUtil.traceCombatIfNeeded(game,game.getCombat());
}
Program: 158711
Project: 158711
Buggy source:
@Override public boolean canActivate(UUID playerId,Game game){
  if (!controlsAbility(playerId,game) && !game.getContinuousEffects().asThough(getSourceId(),AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE,playerId,game)) {
    return false;
  }
  return game.getPlayer(playerId).canPlayLand();
}

Fixed version (ground truth):
@Override public boolean canActivate(UUID playerId,Game game){
  if (!controlsAbility(playerId,game) && !game.getContinuousEffects().asThough(getSourceId(),AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE,playerId,game)) {
    return false;
  }
  return game.getActivePlayerId().equals(playerId) && game.getPlayer(playerId).canPlayLand();
}
Program: 158712
Project: 158712
Buggy source:
@Override public boolean playLand(Card card,Game game,boolean ignoreTiming){
  ActivatedAbility playLandAbility=null;
  boolean found=false;
  for (  Ability ability : card.getAbilities()) {
    if ((ability instanceof AlternativeSourceCosts) || (ability instanceof OptionalAdditionalSourceCosts)) {
      found=true;
    }
    if (ability instanceof PlayLandAbility) {
      playLandAbility=(ActivatedAbility)ability;
    }
  }
  if (found) {
    SpellAbility spellAbility=new SpellAbility(null,"String_Node_Str",game.getState().getZone(card.getId()),SpellAbilityType.FACE_DOWN_CREATURE);
    spellAbility.setControllerId(this.getId());
    spellAbility.setSourceId(card.getId());
    if (cast(spellAbility,game,false)) {
      return true;
    }
  }
  if (playLandAbility == null) {
    return false;
  }
  if (!playLandAbility.canActivate(this.playerId,game)) {
    return false;
  }
  if (ignoreTiming) {
    if (!game.getActivePlayerId().equals(playerId)) {
      return false;
    }
  }
 else   if (!game.canPlaySorcery(playerId)) {
    return false;
  }
  if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND,card.getId(),card.getId(),playerId))) {
    if (moveCards(card,Zone.BATTLEFIELD,playLandAbility,game,false,false,false,null)) {
      landsPlayed++;
      game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LAND_PLAYED,card.getId(),card.getId(),playerId));
      game.fireInformEvent(getLogName() + "String_Node_Str" + card.getLogName());
      resetStoredBookmark(game);
      return true;
    }
  }
  return true;
}

Fixed version (ground truth):
@Override public boolean playLand(Card card,Game game,boolean ignoreTiming){
  ActivatedAbility playLandAbility=null;
  boolean found=false;
  for (  Ability ability : card.getAbilities()) {
    if ((ability instanceof AlternativeSourceCosts) || (ability instanceof OptionalAdditionalSourceCosts)) {
      found=true;
    }
    if (ability instanceof PlayLandAbility) {
      playLandAbility=(ActivatedAbility)ability;
    }
  }
  if (found) {
    SpellAbility spellAbility=new SpellAbility(null,"String_Node_Str",game.getState().getZone(card.getId()),SpellAbilityType.FACE_DOWN_CREATURE);
    spellAbility.setControllerId(this.getId());
    spellAbility.setSourceId(card.getId());
    if (cast(spellAbility,game,false)) {
      return true;
    }
  }
  if (playLandAbility == null) {
    return false;
  }
  if (!playLandAbility.canActivate(this.playerId,game)) {
    return false;
  }
  if (!ignoreTiming && !game.canPlaySorcery(playerId)) {
    return false;
  }
  if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND,card.getId(),card.getId(),playerId))) {
    if (moveCards(card,Zone.BATTLEFIELD,playLandAbility,game,false,false,false,null)) {
      landsPlayed++;
      game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LAND_PLAYED,card.getId(),card.getId(),playerId));
      game.fireInformEvent(getLogName() + "String_Node_Str" + card.getLogName());
      resetStoredBookmark(game);
      return true;
    }
  }
  return true;
}
Program: 158713
Project: 158713
Buggy source:
@Override public boolean replaceEvent(GameEvent event,Ability source,Game game){
  Player player=game.getPlayer(source.getControllerId());
  MageObject sourceObject=game.getObject(source.getSourceId());
  if (player != null && cost != null && sourceObject != null) {
    boolean replace=true;
    if (cost.canPay(source,source.getSourceId(),player.getId(),game)) {
      if (player.chooseUse(outcome,cost.getText() + "String_Node_Str" + sourceObject.getLogName()+ "String_Node_Str",source,game)) {
        cost.clearPaid();
        replace=!cost.pay(source,game,source.getSourceId(),source.getControllerId(),false);
      }
    }
    if (replace) {
      Card card=game.getCard(event.getTargetId());
      if (card != null) {
        player.moveCards(card,game.getState().getZone(event.getTargetId()),Zone.GRAVEYARD,source,game);
      }
      return true;
    }
  }
  return false;
}

Fixed version (ground truth):
@Override public boolean replaceEvent(GameEvent event,Ability source,Game game){
  Player player=game.getPlayer(source.getControllerId());
  MageObject sourceObject=game.getObject(source.getSourceId());
  if (player != null && cost != null && sourceObject != null) {
    boolean replace=true;
    if (cost.canPay(source,source.getSourceId(),player.getId(),game)) {
      if (player.chooseUse(outcome,cost.getText() + "String_Node_Str" + sourceObject.getLogName()+ "String_Node_Str",source,game)) {
        cost.clearPaid();
        replace=!cost.pay(source,game,source.getSourceId(),source.getControllerId(),false);
      }
    }
    if (replace) {
      Card card=game.getCard(event.getTargetId());
      if (card != null) {
        player.moveCards(card,Zone.GRAVEYARD,source,game);
      }
      return true;
    }
  }
  return false;
}
Program: 158714
Project: 158714
Buggy source:
@Override public void resume(){
  playerList=state.getPlayerList(state.getActivePlayerId());
  Player player=getPlayer(playerList.get());
  boolean wasPaused=state.isPaused();
  state.resume();
  if (!gameOver(null)) {
    fireInformEvent(new StringBuilder("String_Node_Str").append(state.getTurnNum()).toString());
    if (checkStopOnTurnOption()) {
      return;
    }
    state.getTurn().resumePlay(this,wasPaused);
    if (!isPaused() && !gameOver(null)) {
      endOfTurn();
      player=playerList.getNext(this);
      state.setTurnNum(state.getTurnNum() + 1);
    }
  }
  play(player.getId());
}

Fixed version (ground truth):
@Override public void resume(){
  playerList=state.getPlayerList(state.getActivePlayerId());
  Player player=getPlayer(playerList.get());
  boolean wasPaused=state.isPaused();
  state.resume();
  if (!gameOver(null)) {
    fireInformEvent("String_Node_Str" + state.getTurnNum());
    if (checkStopOnTurnOption()) {
      return;
    }
    state.getTurn().resumePlay(this,wasPaused);
    if (!isPaused() && !gameOver(null)) {
      endOfTurn();
      player=playerList.getNext(this);
      state.setTurnNum(state.getTurnNum() + 1);
    }
  }
  play(player.getId());
}
Program: 158716
Project: 158716
Buggy source:
@Override public boolean playLand(Card card,Game game){
  ActivatedAbility playLandAbility=null;
  boolean found=false;
  for (  Ability ability : card.getAbilities()) {
    if ((ability instanceof AlternativeSourceCosts) || (ability instanceof OptionalAdditionalSourceCosts)) {
      found=true;
    }
    if (ability instanceof PlayLandAbility) {
      playLandAbility=(ActivatedAbility)ability;
    }
  }
  if (found) {
    SpellAbility spellAbility=new SpellAbility(null,"String_Node_Str",game.getState().getZone(card.getId()),SpellAbilityType.FACE_DOWN_CREATURE);
    spellAbility.setControllerId(this.getId());
    spellAbility.setSourceId(card.getId());
    if (cast(spellAbility,game,false)) {
      return true;
    }
  }
  if (playLandAbility == null) {
    return false;
  }
  if (!playLandAbility.canActivate(this.playerId,game)) {
    return false;
  }
  if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND,card.getId(),card.getId(),playerId))) {
    if (moveCards(card,Zone.BATTLEFIELD,playLandAbility,game,false,false,false,null)) {
      landsPlayed++;
      game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LAND_PLAYED,card.getId(),card.getId(),playerId));
      game.fireInformEvent(getLogName() + "String_Node_Str" + card.getLogName());
      resetStoredBookmark(game);
      return true;
    }
  }
  return false;
}

Fixed version (ground truth):
@Override public boolean playLand(Card card,Game game){
  ActivatedAbility playLandAbility=null;
  boolean found=false;
  for (  Ability ability : card.getAbilities()) {
    if ((ability instanceof AlternativeSourceCosts) || (ability instanceof OptionalAdditionalSourceCosts)) {
      found=true;
    }
    if (ability instanceof PlayLandAbility) {
      playLandAbility=(ActivatedAbility)ability;
    }
  }
  if (found) {
    SpellAbility spellAbility=new SpellAbility(null,"String_Node_Str",game.getState().getZone(card.getId()),SpellAbilityType.FACE_DOWN_CREATURE);
    spellAbility.setControllerId(this.getId());
    spellAbility.setSourceId(card.getId());
    if (cast(spellAbility,game,false)) {
      return true;
    }
  }
  if (playLandAbility == null) {
    return false;
  }
  if (!playLandAbility.canActivate(this.playerId,game)) {
    return false;
  }
  if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND,card.getId(),card.getId(),playerId))) {
    if (moveCards(card,Zone.BATTLEFIELD,playLandAbility,game,false,false,false,null)) {
      landsPlayed++;
      game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LAND_PLAYED,card.getId(),card.getId(),playerId));
      game.fireInformEvent(getLogName() + "String_Node_Str" + card.getLogName());
      resetStoredBookmark(game);
      return true;
    }
  }
  return true;
}
Program: 158717
Project: 158717
Buggy source:
private UUID getSourceControllerId(UUID sourceId,Game game){
  StackObject source=game.getStack().getStackObject(sourceId);
  if (source != null) {
    return source.getControllerId();
  }
  Permanent permanent=game.getBattlefield().getPermanent(sourceId);
  if (permanent != null) {
    return permanent.getControllerId();
  }
  return null;
}

Fixed version (ground truth):
private UUID getSourceControllerId(UUID sourceId,Game game){
  StackObject source=game.getStack().getStackObject(sourceId);
  if (source != null) {
    return source.getControllerId();
  }
  Permanent permanent=game.getBattlefield().getPermanent(sourceId);
  if (permanent != null) {
    return permanent.getControllerId();
  }
  return game.getContinuousEffects().getControllerOfSourceId(sourceId);
}
Program: 158718
Project: 158718
Buggy source:
@Override public boolean checkTrigger(GameEvent event,Game game){
  if (((ZoneChangeEvent)event).isDiesEvent()) {
    ZoneChangeEvent zEvent=(ZoneChangeEvent)event;
    boolean triggered=false;
    if (zEvent.getTarget().getAttachments().contains(this.getSourceId())) {
      triggered=true;
    }
 else {
      Permanent attachment=game.getPermanentOrLKIBattlefield(getSourceId());
      if (attachment != null && zEvent.getTargetId() != null && attachment.getAttachedTo() != null && zEvent.getTargetId().equals(attachment.getAttachedTo()) && attachment.getAttachedToZoneChangeCounter() == zEvent.getTarget().getZoneChangeCounter(game) - 1) {
        triggered=true;
      }
    }
    if (triggered) {
      for (      Effect effect : getEffects()) {
        effect.setValue("String_Node_Str",zEvent.getTarget());
        if (setTargetPointer.equals(SetTargetPointer.ATTACHED_TO_CONTROLLER)) {
          Permanent attachment=game.getPermanentOrLKIBattlefield(getSourceId());
          if (attachment != null && attachment.getAttachedTo() != null) {
            Permanent attachedTo=(Permanent)game.getLastKnownInformation(attachment.getAttachedTo(),Zone.BATTLEFIELD,attachment.getAttachedToZoneChangeCounter());
            if (attachedTo != null) {
              effect.setTargetPointer(new FixedTarget(attachedTo.getControllerId()));
            }
          }
        }
      }
      return true;
    }
  }
  return false;
}

Fixed version (ground truth):
@Override public boolean checkTrigger(GameEvent event,Game game){
  if (((ZoneChangeEvent)event).isDiesEvent()) {
    ZoneChangeEvent zEvent=(ZoneChangeEvent)event;
    boolean triggered=false;
    if (zEvent.getTarget().getAttachments().contains(this.getSourceId())) {
      triggered=true;
    }
 else {
      Permanent attachment=game.getPermanentOrLKIBattlefield(getSourceId());
      if (attachment != null && zEvent.getTargetId() != null && attachment.getAttachedTo() != null && zEvent.getTargetId().equals(attachment.getAttachedTo())) {
        Permanent attachedTo=game.getPermanentOrLKIBattlefield(attachment.getAttachedTo());
        if (attachedTo != null && attachment.getAttachedToZoneChangeCounter() == attachedTo.getZoneChangeCounter(game)) {
          triggered=true;
        }
      }
    }
    if (triggered) {
      for (      Effect effect : getEffects()) {
        effect.setValue("String_Node_Str",zEvent.getTarget());
        if (setTargetPointer.equals(SetTargetPointer.ATTACHED_TO_CONTROLLER)) {
          Permanent attachment=game.getPermanentOrLKIBattlefield(getSourceId());
          if (attachment != null && attachment.getAttachedTo() != null) {
            Permanent attachedTo=(Permanent)game.getLastKnownInformation(attachment.getAttachedTo(),Zone.BATTLEFIELD,attachment.getAttachedToZoneChangeCounter());
            if (attachedTo != null) {
              effect.setTargetPointer(new FixedTarget(attachedTo.getControllerId()));
            }
          }
        }
      }
      return true;
    }
  }
  return false;
}
Program: 158720
Project: 158720
Buggy source:
@Override public boolean canTarget(UUID id,Ability source,Game game){
  StackObject stackObject=game.getStack().getStackObject(id);
  if ((stackObject instanceof Spell) || (stackObject instanceof StackAbility)) {
    return true;
  }
  return false;
}

Fixed version (ground truth):
@Override public boolean canTarget(UUID id,Ability source,Game game){
  StackObject stackObject=game.getStack().getStackObject(id);
  return (stackObject instanceof Spell) || (stackObject instanceof StackAbility);
}
Program: 158721
Project: 158721
Buggy source:
public boolean counter(UUID objectId,UUID sourceId,Game game,Zone zone,boolean owner,boolean onTop){
  StackObject stackObject=getStackObject(objectId);
  MageObject sourceObject=game.getObject(sourceId);
  if (stackObject != null && sourceObject != null) {
    MageObject targetSourceObject=game.getObject(stackObject.getSourceId());
    String counteredObjectName, targetSourceName;
    if (targetSourceObject == null) {
      targetSourceName="String_Node_Str";
    }
 else {
      targetSourceName=game.getObject(stackObject.getSourceId()).getLogName();
    }
    if (stackObject instanceof Spell) {
      counteredObjectName=targetSourceName;
    }
 else {
      counteredObjectName="String_Node_Str" + stackObject.getStackAbility().getRule(targetSourceName) + "String_Node_Str"+ targetSourceName;
    }
    if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.COUNTER,objectId,sourceId,stackObject.getControllerId()))) {
      stackObject.counter(sourceId,game,zone,owner,onTop);
      if (!game.isSimulation()) {
        game.informPlayers(counteredObjectName + "String_Node_Str" + sourceObject.getLogName());
      }
      game.fireEvent(GameEvent.getEvent(GameEvent.EventType.COUNTERED,objectId,sourceId,stackObject.getControllerId()));
    }
 else     if (!game.isSimulation()) {
      game.informPlayers(counteredObjectName + "String_Node_Str" + sourceObject.getLogName());
    }
    return true;
  }
  return false;
}

Fixed version (ground truth):
public boolean counter(UUID objectId,UUID sourceId,Game game,Zone zone,boolean owner,boolean onTop){
  StackObject stackObject=getStackObject(objectId);
  MageObject sourceObject=game.getObject(sourceId);
  if (stackObject != null && sourceObject != null) {
    MageObject targetSourceObject=game.getObject(stackObject.getSourceId());
    String counteredObjectName, targetSourceName;
    if (targetSourceObject == null) {
      targetSourceName="String_Node_Str";
    }
 else {
      targetSourceName=game.getObject(stackObject.getSourceId()).getLogName();
    }
    if (stackObject instanceof Spell) {
      counteredObjectName=targetSourceName;
    }
 else {
      counteredObjectName="String_Node_Str" + stackObject.getStackAbility().getRule(targetSourceName) + "String_Node_Str"+ targetSourceName;
    }
    if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.COUNTER,objectId,sourceId,stackObject.getControllerId()))) {
      if (!(stackObject instanceof Spell)) {
        this.remove(stackObject);
      }
      stackObject.counter(sourceId,game,zone,owner,onTop);
      if (!game.isSimulation()) {
        game.informPlayers(counteredObjectName + "String_Node_Str" + sourceObject.getLogName());
      }
      game.fireEvent(GameEvent.getEvent(GameEvent.EventType.COUNTERED,objectId,sourceId,stackObject.getControllerId()));
    }
 else     if (!game.isSimulation()) {
      game.informPlayers(counteredObjectName + "String_Node_Str" + sourceObject.getLogName());
    }
    return true;
  }
  return false;
}
Program: 158722
Project: 158722
Buggy source:
@Override public boolean apply(Game game,Ability source){
  Card card=game.getCard(source.getFirstTarget());
  Permanent permanent=game.getPermanentEntering(source.getSourceId());
  if (permanent == null) {
    permanent=game.getPermanent(source.getSourceId());
  }
  if (permanent != null) {
    permanent.setName(card.getName());
    permanent.getColor(game).setColor(card.getColor(game));
    permanent.getManaCost().clear();
    permanent.getManaCost().add(card.getManaCost());
    permanent.getCardType().clear();
    for (    CardType type : card.getCardType()) {
      permanent.getCardType().add(type);
    }
    permanent.getSubtype().clear();
    for (    String type : card.getSubtype()) {
      permanent.getSubtype().add(type);
    }
    permanent.getSupertype().clear();
    for (    String type : card.getSupertype()) {
      permanent.getSupertype().add(type);
    }
    permanent.setExpansionSetCode(card.getExpansionSetCode());
    permanent.getAbilities().clear();
    for (    Ability ability : card.getAbilities()) {
      permanent.addAbility(ability,game);
    }
    return true;
  }
  return false;
}

Fixed version (ground truth):
@Override public Boolean apply(Game game,MageObject mageObject){
  mageObject.getPower().initValue(7);
  mageObject.getToughness().initValue(7);
  return true;
}
Program: 158723
Project: 158723
Buggy source:
@Override public QuicksilverGargantuanCopyEffect copy(){
  return new QuicksilverGargantuanCopyEffect(this);
}

Fixed version (ground truth):
@Override public QuicksilverGargantuan copy(){
  return new QuicksilverGargantuan(this);
}
Program: 158724
Project: 158724
Buggy source:
@Override public boolean apply(Game game,Ability source){
  Player controller=game.getPlayer(source.getControllerId());
  if (controller != null) {
    if (controller.getLibrary().size() > 0) {
      Card card=controller.getLibrary().removeFromBottom(game);
      if (card != null) {
        controller.moveCards(card,Zone.LIBRARY,Zone.GRAVEYARD,source,game);
        if (card.getCardType().contains(CardType.CREATURE)) {
          Permanent sourcePermanent=game.getPermanentOrLKIBattlefield(source.getSourceId());
          if (sourcePermanent != null && card.getPower().getValue() <= sourcePermanent.getPower().getValue()) {
            controller.moveCards(card,Zone.BATTLEFIELD,source,game);
          }
        }
      }
    }
    return true;
  }
  return false;
}

Fixed version (ground truth):
@Override public boolean apply(Game game,Ability source){
  Player controller=game.getPlayer(source.getControllerId());
  if (controller != null) {
    if (controller.getLibrary().size() > 0) {
      Card card=controller.getLibrary().getFromBottom(game);
      if (card != null) {
        controller.moveCards(card,Zone.GRAVEYARD,source,game);
        if (card.getCardType().contains(CardType.CREATURE)) {
          Permanent sourcePermanent=game.getPermanentOrLKIBattlefield(source.getSourceId());
          if (sourcePermanent != null && card.getPower().getValue() <= sourcePermanent.getPower().getValue()) {
            controller.moveCards(card,Zone.BATTLEFIELD,source,game);
          }
        }
      }
    }
    return true;
  }
  return false;
}
Program: 158725
Project: 158725
Buggy source:
/** 
 * If the AI on a local server gets control of a Basalt Monolith it will infinite loop taping for three mana and then using the mana to untap lol. Seeing the computer durdle troll is quite the hillarious thing
 */
@Test public void testBasaltMonolith(){
  addCard(Zone.BATTLEFIELD,playerA,"String_Node_Str",1);
  setStopAt(1,PhaseStep.END_TURN);
  execute();
  assertTapped("String_Node_Str",false);
}

Fixed version (ground truth):
/** 
 * If the AI on a local server gets control of a Basalt Monolith it will infinite loop taping for three mana and then using the mana to untap lol. Seeing the computer durdle troll is quite the hillarious thing
 */
@Test public void testBasaltMonolith(){
  addCard(Zone.HAND,playerA,"String_Node_Str",1);
  addCard(Zone.BATTLEFIELD,playerA,"String_Node_Str",3);
  addCard(Zone.BATTLEFIELD,playerA,"String_Node_Str",1,true);
  setStopAt(5,PhaseStep.END_TURN);
  execute();
  assertPermanentCount(playerA,"String_Node_Str",1);
  assertTapped("String_Node_Str",true);
  assertTappedCount("String_Node_Str",false,3);
}
Program: 158726
Project: 158726
Buggy source:
@Override public void clearPaid(){
  super.clearPaid();
  this.cards.clear();
  this.targets.clear();
}

Fixed version (ground truth):
@Override public void clearPaid(){
  super.clearPaid();
  this.cards.clear();
  this.targets.clearChosen();
}
Program: 158727
Project: 158727
Buggy source:
public DiscardTargetCost(DiscardTargetCost cost){
  super(cost);
  for (  Card card : cost.cards) {
    this.cards.add(card.copy());
  }
  this.randomDiscard=cost.randomDiscard;
}

Fixed version (ground truth):
public DiscardTargetCost(DiscardTargetCost cost){
  super(cost);
  this.cards.addAll(cost.cards);
  this.randomDiscard=cost.randomDiscard;
}
Program: 158728
Project: 158728
Buggy source:
@Override public boolean pay(Ability ability,Game game,UUID sourceId,UUID controllerId,boolean noMana){
  this.cards.clear();
  this.targets.clearChosen();
  ;
  Player player=game.getPlayer(controllerId);
  if (player == null) {
    return false;
  }
  int amount=this.getTargets().get(0).getNumberOfTargets();
  if (randomDiscard) {
    this.cards.addAll(player.discard(amount,true,ability,game).getCards(game));
  }
 else {
    if (targets.choose(Outcome.Discard,controllerId,sourceId,game)) {
      for (      UUID targetId : targets.get(0).getTargets()) {
        Card card=player.getHand().get(targetId,game);
        if (card == null) {
          return false;
        }
        player.discard(card,ability,game);
        this.cards.add(card.copy());
      }
    }
  }
  paid=cards.size() >= amount;
  return paid;
}

Fixed version (ground truth):
@Override public boolean pay(Ability ability,Game game,UUID sourceId,UUID controllerId,boolean noMana){
  this.cards.clear();
  this.targets.clearChosen();
  ;
  Player player=game.getPlayer(controllerId);
  if (player == null) {
    return false;
  }
  int amount=this.getTargets().get(0).getNumberOfTargets();
  if (randomDiscard) {
    this.cards.addAll(player.discard(amount,true,ability,game).getCards(game));
  }
 else {
    if (targets.choose(Outcome.Discard,controllerId,sourceId,game)) {
      for (      UUID targetId : targets.get(0).getTargets()) {
        Card card=player.getHand().get(targetId,game);
        if (card == null) {
          return false;
        }
        player.discard(card,ability,game);
        this.cards.add(card);
      }
    }
  }
  paid=cards.size() >= amount;
  return paid;
}
Program: 158729
Project: 158729
Buggy source:
@Override public boolean apply(Game game,Ability source){
  Player player=game.getPlayer(source.getControllerId());
  Permanent permanent=game.getPermanentOrLKIBattlefield(source.getSourceId());
  MageObject sourceObject=source.getSourceObject(game);
  if (sourceObject != null && player != null && permanent != null) {
    StringBuilder sb=new StringBuilder(cost.getText()).append("String_Node_Str");
    if (!sb.toString().toLowerCase().startsWith("String_Node_Str") && !sb.toString().toLowerCase().startsWith("String_Node_Str")) {
      sb.insert(0,"String_Node_Str");
    }
    String message=CardUtil.replaceSourceName(sb.toString(),sourceObject.getLogName());
    message=Character.toUpperCase(message.charAt(0)) + message.substring(1);
    if (player.chooseUse(Outcome.Benefit,message,source,game)) {
      cost.clearPaid();
      if (cost.pay(source,game,source.getSourceId(),source.getControllerId(),false)) {
        return true;
      }
    }
    permanent.sacrifice(source.getSourceId(),game);
    return true;
  }
  return false;
}

Fixed version (ground truth):
@Override public boolean apply(Game game,Ability source){
  Player player=game.getPlayer(source.getControllerId());
  Permanent sourcePermanent=game.getPermanentOrLKIBattlefield(source.getSourceId());
  if (player != null && sourcePermanent != null) {
    StringBuilder sb=new StringBuilder(cost.getText()).append("String_Node_Str");
    if (!sb.toString().toLowerCase().startsWith("String_Node_Str") && !sb.toString().toLowerCase().startsWith("String_Node_Str")) {
      sb.insert(0,"String_Node_Str");
    }
    String message=CardUtil.replaceSourceName(sb.toString(),sourcePermanent.getLogName());
    message=Character.toUpperCase(message.charAt(0)) + message.substring(1);
    if (player.chooseUse(Outcome.Benefit,message,source,game)) {
      cost.clearPaid();
      if (cost.pay(source,game,source.getSourceId(),source.getControllerId(),false)) {
        return true;
      }
    }
    sourcePermanent.sacrifice(source.getSourceId(),game);
    return true;
  }
  return false;
}
Program: 158730
Project: 158730
Buggy source:
@Override public boolean apply(Game game,Ability source){
  Player controller=game.getPlayer(source.getControllerId());
  if (controller != null) {
    Map<UUID,Set<UUID>> exiledCards=new HashMap<>();
    for (    UUID playerId : game.getState().getPlayersInRange(controller.getId(),game)) {
      Player player=game.getPlayer(playerId);
      if (player != null) {
        Set cards=player.getGraveyard().getCards(new FilterArtifactCard(),game);
        controller.moveCards(cards,Zone.EXILED,source,game);
        exiledCards.put(player.getId(),cards);
      }
    }
    for (    UUID playerId : game.getState().getPlayersInRange(controller.getId(),game)) {
      Player player=game.getPlayer(playerId);
      if (player != null) {
        for (        Permanent permanent : game.getBattlefield().getAllActivePermanents(new FilterArtifactPermanent(),playerId,game)) {
          permanent.sacrifice(source.getSourceId(),game);
        }
      }
    }
    for (    UUID playerId : game.getState().getPlayersInRange(controller.getId(),game)) {
      Player player=game.getPlayer(playerId);
      if (player != null) {
        Cards playersExiledCards=new CardsImpl(exiledCards.get(playerId));
        controller.moveCards(playersExiledCards,Zone.BATTLEFIELD,source,game);
      }
    }
    return true;
  }
  return false;
}

Fixed version (ground truth):
@Override public boolean apply(Game game,Ability source){
  Player controller=game.getPlayer(source.getControllerId());
  if (controller != null) {
    Map<UUID,Set<Card>> exiledCards=new HashMap<>();
    for (    UUID playerId : game.getState().getPlayersInRange(controller.getId(),game)) {
      Player player=game.getPlayer(playerId);
      if (player != null) {
        Set<Card> cards=player.getGraveyard().getCards(new FilterArtifactCard(),game);
        controller.moveCards(cards,Zone.EXILED,source,game);
        exiledCards.put(player.getId(),cards);
      }
    }
    for (    UUID playerId : game.getState().getPlayersInRange(controller.getId(),game)) {
      Player player=game.getPlayer(playerId);
      if (player != null) {
        for (        Permanent permanent : game.getBattlefield().getAllActivePermanents(new FilterArtifactPermanent(),playerId,game)) {
          permanent.sacrifice(source.getSourceId(),game);
        }
      }
    }
    for (    UUID playerId : game.getState().getPlayersInRange(controller.getId(),game)) {
      Player player=game.getPlayer(playerId);
      if (player != null) {
        controller.moveCards(exiledCards.get(playerId),Zone.BATTLEFIELD,source,game);
      }
    }
    return true;
  }
  return false;
}
Program: 158731
Project: 158731
Buggy source:
@Override public boolean apply(Game game,Ability source){
  Player controller=game.getPlayer(source.getControllerId());
  Player targetPlayer=game.getPlayer(getTargetPointer().getFirst(game,source));
  if (controller != null && targetPlayer != null) {
    FilterLandCard filter=new FilterLandCard();
    filter.add(new OwnerIdPredicate(targetPlayer.getId()));
    Cards exiledCards=new CardsImpl();
    exiledCards.addAll(game.getExile().getAllCards(game));
    Cards exiledLands=new CardsImpl();
    exiledLands.addAll(exiledCards.getCards(filter,source.getSourceId(),controller.getId(),game));
    if (!exiledLands.isEmpty() && controller.chooseUse(outcome,"String_Node_Str",source,game)) {
      FilterCard filterToPlay=new FilterCard("String_Node_Str" + (exiledLands.size() > 1 ? "String_Node_Str" : "String_Node_Str") + "String_Node_Str"+ targetPlayer.getName()+ "String_Node_Str");
      TargetCard targetCards=new TargetCard(0,exiledLands.size(),Zone.EXILED,filterToPlay);
      if (controller.chooseTarget(outcome,exiledLands,targetCards,source,game)) {
        controller.moveCards(new CardsImpl(targetCards.getTargets()),null,Zone.BATTLEFIELD,source,game);
      }
    }
    return true;
  }
  return false;
}

Fixed version (ground truth):
@Override public boolean apply(Game game,Ability source){
  Player controller=game.getPlayer(source.getControllerId());
  Player targetPlayer=game.getPlayer(getTargetPointer().getFirst(game,source));
  if (controller != null && targetPlayer != null) {
    FilterLandCard filter=new FilterLandCard();
    filter.add(new OwnerIdPredicate(targetPlayer.getId()));
    Cards exiledCards=new CardsImpl();
    exiledCards.addAll(game.getExile().getAllCards(game));
    Cards exiledLands=new CardsImpl();
    exiledLands.addAll(exiledCards.getCards(filter,source.getSourceId(),controller.getId(),game));
    if (!exiledLands.isEmpty() && controller.chooseUse(outcome,"String_Node_Str",source,game)) {
      FilterCard filterToPlay=new FilterCard("String_Node_Str" + (exiledLands.size() > 1 ? "String_Node_Str" : "String_Node_Str") + "String_Node_Str"+ targetPlayer.getName()+ "String_Node_Str");
      TargetCard targetCards=new TargetCard(0,exiledLands.size(),Zone.EXILED,filterToPlay);
      if (controller.chooseTarget(outcome,exiledLands,targetCards,source,game)) {
        controller.moveCards(new CardsImpl(targetCards.getTargets()),Zone.BATTLEFIELD,source,game);
      }
    }
    return true;
  }
  return false;
}
Program: 158732
Project: 158732
Buggy source:
@Override public boolean chooseTarget(Outcome outcome,Cards cards,TargetCard target,Ability source,Game game){
  if (!targets.isEmpty()) {
    for (    String targetDefinition : targets) {
      String[] targetList=targetDefinition.split("String_Node_Str");
      boolean targetFound=false;
      for (      String targetName : targetList) {
        for (        Card card : cards.getCards(game)) {
          if (card.getName().equals(targetName)) {
            target.add(card.getId(),game);
            targetFound=true;
            break;
          }
        }
      }
      if (targetFound) {
        targets.remove(targetDefinition);
        return true;
      }
    }
  }
  return computerPlayer.chooseTarget(outcome,cards,target,source,game);
}

Fixed version (ground truth):
@Override public boolean chooseTarget(Outcome outcome,Cards cards,TargetCard target,Ability source,Game game){
  if (!targets.isEmpty()) {
    for (    String targetDefinition : targets) {
      String[] targetList=targetDefinition.split("String_Node_Str");
      boolean targetFound=false;
      for (      String targetName : targetList) {
        for (        Card card : cards.getCards(game)) {
          if (card.getName().equals(targetName) && !target.getTargets().contains(card.getId())) {
            target.add(card.getId(),game);
            targetFound=true;
            break;
          }
        }
      }
      if (targetFound) {
        targets.remove(targetDefinition);
        return true;
      }
    }
  }
  return computerPlayer.chooseTarget(outcome,cards,target,source,game);
}
Program: 158734
Project: 158734
Buggy source:
@Override public boolean apply(Game game,Ability source){
  Player controller=game.getPlayer(source.getControllerId());
  Permanent sourcePermanent=game.getPermanent(source.getSourceId());
  if (controller != null) {
    Choice choice=new ChoiceImpl(true);
    choice.setMessage(choiceMessage);
    choice.getChoices().addAll(modes);
    while (!choice.isChosen()) {
      if (!controller.canRespond()) {
        return false;
      }
      controller.choose(Outcome.Neutral,choice,game);
    }
    if (choice.isChosen()) {
      if (!game.isSimulation())       game.informPlayers(new StringBuilder(sourcePermanent.getLogName()).append("String_Node_Str").append(controller.getLogName()).append("String_Node_Str").append(choice.getChoice()).toString());
      game.getState().setValue(source.getSourceId() + "String_Node_Str",choice.getChoice());
      sourcePermanent.addInfo("String_Node_Str","String_Node_Str" + choice.getChoice() + "String_Node_Str",game);
    }
    return true;
  }
  return false;
}

Fixed version (ground truth):
@Override public boolean apply(Game game,Ability source){
  Player controller=game.getPlayer(source.getControllerId());
  Permanent sourcePermanent=game.getPermanent(source.getSourceId());
  if (sourcePermanent == null) {
    sourcePermanent=game.getPermanentEntering(source.getSourceId());
  }
  if (controller != null) {
    Choice choice=new ChoiceImpl(true);
    choice.setMessage(choiceMessage);
    choice.getChoices().addAll(modes);
    while (!choice.isChosen()) {
      if (!controller.canRespond()) {
        return false;
      }
      controller.choose(Outcome.Neutral,choice,game);
    }
    if (choice.isChosen()) {
      if (!game.isSimulation()) {
        game.informPlayers(new StringBuilder(sourcePermanent.getLogName()).append("String_Node_Str").append(controller.getLogName()).append("String_Node_Str").append(choice.getChoice()).toString());
      }
      game.getState().setValue(source.getSourceId() + "String_Node_Str",choice.getChoice());
      sourcePermanent.addInfo("String_Node_Str","String_Node_Str" + choice.getChoice() + "String_Node_Str",game);
    }
    return true;
  }
  return false;
}
Program: 158735
Project: 158735
Buggy source:
protected void activateAbility(LinkedHashMap<UUID,? extends ActivatedAbility> abilities,MageObject object,Game game){
  updateGameStatePriority("String_Node_Str",game);
  if (abilities.size() == 1 && suppressAbilityPicker(abilities.values().iterator().next())) {
    ActivatedAbility ability=abilities.values().iterator().next();
    if (ability.getTargets().size() != 0 || !(ability.getCosts().size() == 1 && ability.getCosts().get(0) instanceof SacrificeSourceCost)) {
      activateAbility(ability,game);
      return;
    }
  }
  game.fireGetChoiceEvent(playerId,name,object,new ArrayList<>(abilities.values()));
  waitForResponse(game);
  if (response.getUUID() != null) {
    if (abilities.containsKey(response.getUUID())) {
      activateAbility(abilities.get(response.getUUID()),game);
    }
  }
}

Fixed version (ground truth):
protected void activateAbility(LinkedHashMap<UUID,? extends ActivatedAbility> abilities,MageObject object,Game game){
  updateGameStatePriority("String_Node_Str",game);
  if (abilities.size() == 1 && suppressAbilityPicker(abilities.values().iterator().next())) {
    ActivatedAbility ability=abilities.values().iterator().next();
    if (ability.getTargets().size() != 0 || !(ability.getCosts().size() == 1 && ability.getCosts().get(0) instanceof SacrificeSourceCost) || !(ability.getCosts().size() == 2 && ability.getCosts().get(0) instanceof TapSourceCost && ability.getCosts().get(0) instanceof SacrificeSourceCost)) {
      activateAbility(ability,game);
      return;
    }
  }
  game.fireGetChoiceEvent(playerId,name,object,new ArrayList<>(abilities.values()));
  waitForResponse(game);
  if (response.getUUID() != null) {
    if (abilities.containsKey(response.getUUID())) {
      activateAbility(abilities.get(response.getUUID()),game);
    }
  }
}
Program: 158737
Project: 158737
Buggy source:
@Override public boolean apply(Game game,Ability source){
  Player controller=game.getPlayer(source.getControllerId());
  Permanent sourcePermanent=game.getPermanent(source.getSourceId());
  if (sourcePermanent == null) {
    sourcePermanent=game.getPermanentEntering(source.getSourceId());
  }
  if (controller != null) {
    Choice choice=new ChoiceImpl(true);
    choice.setMessage(choiceMessage);
    choice.getChoices().addAll(modes);
    while (!choice.isChosen()) {
      if (!controller.canRespond()) {
        return false;
      }
      controller.choose(Outcome.Neutral,choice,game);
    }
    if (choice.isChosen()) {
      if (!game.isSimulation()) {
        game.informPlayers(new StringBuilder(sourcePermanent.getLogName()).append("String_Node_Str").append(controller.getLogName()).append("String_Node_Str").append(choice.getChoice()).toString());
      }
      game.getState().setValue(source.getSourceId() + "String_Node_Str",choice.getChoice());
      sourcePermanent.addInfo("String_Node_Str","String_Node_Str" + choice.getChoice() + "String_Node_Str",game);
    }
    return true;
  }
  return false;
}

Fixed version (ground truth):
@Override public boolean apply(Game game,Ability source){
  Player controller=game.getPlayer(source.getControllerId());
  Permanent sourcePermanent=game.getPermanent(source.getSourceId());
  if (sourcePermanent == null) {
    sourcePermanent=game.getPermanentEntering(source.getSourceId());
  }
  if (controller != null) {
    Choice choice=new ChoiceImpl(true);
    choice.setMessage(choiceMessage);
    choice.getChoices().addAll(modes);
    while (!choice.isChosen()) {
      if (!controller.canRespond()) {
        return false;
      }
      controller.choose(Outcome.Neutral,choice,game);
    }
    if (choice.isChosen()) {
      if (!game.isSimulation()) {
        game.informPlayers(sourcePermanent.getLogName() + "String_Node_Str" + controller.getLogName()+ "String_Node_Str"+ choice.getChoice());
      }
      game.getState().setValue(source.getSourceId() + "String_Node_Str",choice.getChoice());
      sourcePermanent.addInfo("String_Node_Str","String_Node_Str" + choice.getChoice() + "String_Node_Str",game);
    }
    return true;
  }
  return false;
}
Program: 158738
Project: 158738
Buggy source:
/** 
 * Isochron Scepter Artifact, 2 (2) Imprint — When Isochron Scepter enters the battlefield, you may exile an  instant card with converted mana cost 2 or less from your hand. {2}, {T}: You may copy the exiled card. If you do, you may cast the copy  without paying its mana cost.
 */
@Test public void testImprint(){
  addCard(Zone.BATTLEFIELD,playerA,"String_Node_Str",4);
  addCard(Zone.HAND,playerA,"String_Node_Str");
  addCard(Zone.HAND,playerA,"String_Node_Str");
  castSpell(1,PhaseStep.PRECOMBAT_MAIN,playerA,"String_Node_Str");
  addTarget(playerA,"String_Node_Str");
  setStopAt(1,PhaseStep.BEGIN_COMBAT);
  execute();
  assertPermanentCount(playerA,"String_Node_Str",1);
  assertExileCount("String_Node_Str",1);
  assertLife(playerB,20);
}

Fixed version (ground truth):
/** 
 * Isochron Scepter Artifact, 2 (2) Imprint — When Isochron Scepter enters the battlefield, you may exile an instant card with converted mana cost 2 or less from your hand. {2}, {T}: You may copy the exiled card. If you do, you may cast the copy without paying its mana cost.
 */
@Test public void testImprint(){
  addCard(Zone.BATTLEFIELD,playerA,"String_Node_Str",4);
  addCard(Zone.HAND,playerA,"String_Node_Str");
  addCard(Zone.HAND,playerA,"String_Node_Str");
  castSpell(1,PhaseStep.PRECOMBAT_MAIN,playerA,"String_Node_Str");
  addTarget(playerA,"String_Node_Str");
  setStopAt(1,PhaseStep.BEGIN_COMBAT);
  execute();
  assertPermanentCount(playerA,"String_Node_Str",1);
  assertExileCount("String_Node_Str",1);
  assertLife(playerB,20);
}
Program: 158739
Project: 158739
Buggy source:
@Test public void testAngelsGrace(){
  addCard(Zone.BATTLEFIELD,playerA,"String_Node_Str",4);
  addCard(Zone.HAND,playerA,"String_Node_Str");
  addCard(Zone.HAND,playerA,"String_Node_Str");
  addCard(Zone.BATTLEFIELD,playerB,"String_Node_Str",4);
  castSpell(1,PhaseStep.PRECOMBAT_MAIN,playerA,"String_Node_Str");
  addTarget(playerA,"String_Node_Str");
  attack(2,playerB,"String_Node_Str");
  attack(2,playerB,"String_Node_Str");
  attack(2,playerB,"String_Node_Str");
  attack(2,playerB,"String_Node_Str");
  activateAbility(2,PhaseStep.DECLARE_BLOCKERS,playerA,"String_Node_Str");
  setChoice(playerA,"String_Node_Str");
  setChoice(playerA,"String_Node_Str");
  setStopAt(2,PhaseStep.END_COMBAT);
  execute();
  assertPermanentCount(playerA,"String_Node_Str",1);
  assertExileCount("String_Node_Str",1);
  assertGraveyardCount(playerA,"String_Node_Str",0);
  assertLife(playerA,1);
  assertLife(playerB,20);
}

Fixed version (ground truth):
/** 
 * Not sure if it's triggered by just casting Angel's Grace or by casting it from an Isochron Scepter, but when the bug happens neither player is able to play spells or activate abilities anymore for the rest of the game. Maybe something related to Split Second?
 */
@Test public void testAngelsGrace(){
  addCard(Zone.BATTLEFIELD,playerA,"String_Node_Str",4);
  addCard(Zone.HAND,playerA,"String_Node_Str");
  addCard(Zone.HAND,playerA,"String_Node_Str");
  addCard(Zone.BATTLEFIELD,playerB,"String_Node_Str",4);
  addCard(Zone.HAND,playerB,"String_Node_Str",2);
  addCard(Zone.BATTLEFIELD,playerB,"String_Node_Str",2);
  castSpell(1,PhaseStep.PRECOMBAT_MAIN,playerA,"String_Node_Str");
  addTarget(playerA,"String_Node_Str");
  attack(2,playerB,"String_Node_Str");
  attack(2,playerB,"String_Node_Str");
  attack(2,playerB,"String_Node_Str");
  attack(2,playerB,"String_Node_Str");
  activateAbility(2,PhaseStep.DECLARE_BLOCKERS,playerA,"String_Node_Str");
  setChoice(playerA,"String_Node_Str");
  setChoice(playerA,"String_Node_Str");
  castSpell(2,PhaseStep.POSTCOMBAT_MAIN,playerB,"String_Node_Str",playerA);
  castSpell(3,PhaseStep.PRECOMBAT_MAIN,playerB,"String_Node_Str","String_Node_Str");
  setStopAt(3,PhaseStep.BEGIN_COMBAT);
  execute();
  assertExileCount("String_Node_Str",1);
  assertGraveyardCount(playerA,"String_Node_Str",0);
  assertLife(playerA,1);
  assertLife(playerB,20);
  assertGraveyardCount(playerB,"String_Node_Str",2);
  assertGraveyardCount(playerB,"String_Node_Str",1);
  assertPermanentCount(playerB,"String_Node_Str",3);
  assertPermanentCount(playerA,"String_Node_Str",1);
}