diff --git a/Mage.Sets/src/mage/cards/s/SynthesisPod.java b/Mage.Sets/src/mage/cards/s/SynthesisPod.java
new file mode 100644
index 00000000000..1839223e6b2
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SynthesisPod.java
@@ -0,0 +1,165 @@
+package mage.cards.s;
+
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.costs.Cost;
+import mage.abilities.costs.CostImpl;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.InfoEffect;
+import mage.cards.*;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.TargetController;
+import mage.constants.Zone;
+import mage.filter.FilterSpell;
+import mage.game.Game;
+import mage.game.stack.Spell;
+import mage.players.Player;
+import mage.target.TargetSpell;
+import mage.target.common.TargetOpponent;
+import mage.util.CardUtil;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class SynthesisPod extends CardImpl {
+
+ public SynthesisPod(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}{U/P}");
+
+ // ({U/P} can be paid with either {U} or 2 life.)
+ this.addAbility(new SimpleStaticAbility(new InfoEffect("({U/P} can be paid with either {U} or 2 life.)")));
+
+ // {1}{U/P}, {T}, Exile a spell you control: Target opponent reveals cards from the top of their library until they reveal a card with mana value equal to 1 plus the exiled spell's mana value. Exile that card, then that player shuffles. You may cast that exiled card without paying its mana cost.
+ Ability ability = new SimpleActivatedAbility(new SynthesisPodEffect(), new ManaCostsImpl<>("{1}{U/P}"));
+ ability.addCost(new TapSourceCost());
+ ability.addCost(new SynthesisPodCost());
+ ability.addTarget(new TargetOpponent());
+ this.addAbility(ability);
+ }
+
+ private SynthesisPod(final SynthesisPod card) {
+ super(card);
+ }
+
+ @Override
+ public SynthesisPod copy() {
+ return new SynthesisPod(this);
+ }
+}
+
+class SynthesisPodCost extends CostImpl {
+
+ private static final FilterSpell filter = new FilterSpell("a spell you control");
+
+ static {
+ filter.add(TargetController.YOU.getControllerPredicate());
+ }
+
+ private Spell exiledSpell = null;
+
+ SynthesisPodCost() {
+ super();
+ TargetSpell target = new TargetSpell(filter);
+ target.setNotTarget(true);
+ this.addTarget(target);
+ this.text = "Exile a spell you control";
+ }
+
+ private SynthesisPodCost(SynthesisPodCost cost) {
+ super(cost);
+ }
+
+ @Override
+ public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
+ Player player = game.getPlayer(controllerId);
+ if (player == null) {
+ return false;
+ }
+ player.chooseTarget(Outcome.Exile, targets.get(0), source, game);
+ Spell spell = game.getSpell(targets.getFirstTarget());
+ if (spell == null) {
+ return false;
+ }
+ String spellName = spell.getName();
+ exiledSpell = spell;
+ player.moveCards(spell.getCard(), Zone.EXILED, source, game);
+ paid = true;
+ game.informPlayers(player.getLogName() + " exiles " + spellName + " (as costs)");
+ return paid;
+ }
+
+ @Override
+ public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
+ return targets.canChoose(controllerId, source, game);
+ }
+
+ @Override
+ public SynthesisPodCost copy() {
+ return new SynthesisPodCost(this);
+ }
+
+ Spell getExiledSpell() {
+ return exiledSpell;
+ }
+}
+
+class SynthesisPodEffect extends OneShotEffect {
+
+ SynthesisPodEffect() {
+ super(Outcome.Benefit);
+ staticText = "target opponent reveals cards from the top of their library until they reveal a card " +
+ "with mana value equal to 1 plus the exiled spell's mana value. Exile that card, " +
+ "then that player shuffles. You may cast that exiled card without paying its mana cost";
+ }
+
+ private SynthesisPodEffect(final SynthesisPodEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public SynthesisPodEffect copy() {
+ return new SynthesisPodEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ Player opponent = game.getPlayer(getTargetPointer().getFirst(game, source));
+ Spell spell = CardUtil
+ .castStream(source.getCosts(), SynthesisPodCost.class)
+ .map(SynthesisPodCost::getExiledSpell)
+ .findFirst()
+ .orElse(null);
+ if (controller == null || opponent == null || spell == null) {
+ return false;
+ }
+ int mv = spell.getManaValue();
+ Cards cards = new CardsImpl();
+ Card card = getCard(mv, opponent, cards, game);
+ opponent.revealCards(source, cards, game);
+ if (card != null) {
+ controller.moveCards(card, Zone.EXILED, source, game);
+ }
+ opponent.shuffleLibrary(source, game);
+ if (card != null) {
+ CardUtil.castSpellWithAttributesForFree(controller, source, game, card);
+ }
+ return true;
+ }
+
+ private static Card getCard(int mv, Player opponent, Cards cards, Game game) {
+ for (Card card : opponent.getLibrary().getCards(game)) {
+ cards.add(card);
+ if (card.getManaValue() == mv + 1) {
+ return card;
+ }
+ }
+ return null;
+ }
+}
diff --git a/Mage.Sets/src/mage/sets/PhyrexiaAllWillBeOneCommander.java b/Mage.Sets/src/mage/sets/PhyrexiaAllWillBeOneCommander.java
index 016794e88ef..8b5c68aa937 100644
--- a/Mage.Sets/src/mage/sets/PhyrexiaAllWillBeOneCommander.java
+++ b/Mage.Sets/src/mage/sets/PhyrexiaAllWillBeOneCommander.java
@@ -152,6 +152,7 @@ public final class PhyrexiaAllWillBeOneCommander extends ExpansionSet {
cards.add(new SetCardInfo("Soul-Guide Lantern", 142, Rarity.UNCOMMON, mage.cards.s.SoulGuideLantern.class));
cards.add(new SetCardInfo("Sungrass Prairie", 166, Rarity.RARE, mage.cards.s.SungrassPrairie.class));
cards.add(new SetCardInfo("Swords to Plowshares", 89, Rarity.UNCOMMON, mage.cards.s.SwordsToPlowshares.class));
+ cards.add(new SetCardInfo("Synthesis Pod", 23, Rarity.RARE, mage.cards.s.SynthesisPod.class));
cards.add(new SetCardInfo("Tainted Field", 167, Rarity.UNCOMMON, mage.cards.t.TaintedField.class));
cards.add(new SetCardInfo("Tainted Wood", 168, Rarity.UNCOMMON, mage.cards.t.TaintedWood.class));
cards.add(new SetCardInfo("Talisman of Conviction", 143, Rarity.UNCOMMON, mage.cards.t.TalismanOfConviction.class));
diff --git a/Mage/src/main/java/mage/util/CardUtil.java b/Mage/src/main/java/mage/util/CardUtil.java
index 23d987f9342..31c073b67cc 100644
--- a/Mage/src/main/java/mage/util/CardUtil.java
+++ b/Mage/src/main/java/mage/util/CardUtil.java
@@ -1705,6 +1705,10 @@ public final class CardUtil {
return sb.toString();
}
+ public static Stream castStream(Collection> collection, Class clazz) {
+ return castStream(collection.stream(), clazz);
+ }
+
public static Stream castStream(Stream> stream, Class clazz) {
return stream.filter(clazz::isInstance).map(clazz::cast).filter(Objects::nonNull);
}