public static async Task ActAsync(TargetSpaceCtx ctx)
    {
        // target land and a land adjacent to it become a single land for this turn.
        var other = (await ctx.SelectAdjacentLand($"Join {ctx.Space.Label} to.")).Space;

        MultiSpace multi = JoinSpaces(ctx, ctx.Space, other);

        // if you have 4 air:
        if (await ctx.YouHave("4 air"))
        {
            // isolate the joined land.
            var joinedCtx = ctx.Target(multi);
            joinedCtx.Isolate();
            // If it has invaders,
            if (joinedCtx.HasInvaders)
            {
                // 2 fear,
                joinedCtx.AddFear(2);
                // and Remove up to 2 invaders
                await joinedCtx.Invaders.Remove();

                await joinedCtx.Invaders.Remove();
            }
        }
    }
    private static MultiSpace JoinSpaces(SelfCtx originatorCtx, Space space, Space other)
    {
        var gameState = originatorCtx.GameState;

        var multi = new MultiSpace(space, other);

        MoveAllItemsOnSpace(gameState, other, multi);
        MoveAllItemsOnSpace(gameState, space, multi);

        // Pick Board
        var board = space.Board;         // !!! this is not correct when we start having multiple boards.

        // Disconnect space
        var spaceAdjacents = board.Remove(space);
        var otherAdjacents = board.Remove(other);

        // it has the terrain and land # of both lands.
        board.Add(multi, spaceAdjacents.Union(otherAdjacents).Distinct().ToArray());

        // When this effect expires
        gameState.TimePasses_ThisRound.Push(async(gs) => {
            MoveAllItemsOnSpace(gs, multi, space);
            board.Remove(multi);
            board.Add(other, otherAdjacents);
            board.Add(space, spaceAdjacents);

            // divide pieces as you wish.
            await DistributePresence(space, other, gs);
            await DistributeTokens(originatorCtx, space, other, gs);
        });

        return(multi);
    }