* @param cs A <code>ChangeSet</code> to update.
     */
    public void csNewTurn(Random random, ChangeSet cs) {
        logger.finest("ServerPlayer.csNewTurn, for " + getName());

        // Settlements
        List<Settlement> settlements
            = new ArrayList<Settlement>(getSettlements());
        int newSoL = 0;
        for (Settlement settlement : settlements) {
            ((ServerModelObject) settlement).csNewTurn(random, cs);
            newSoL += settlement.getSoL();
        }
        int numberOfColonies = settlements.size();
        if (numberOfColonies > 0) {
            newSoL = newSoL / numberOfColonies;
            if (oldSoL / 10 != newSoL / 10) {
                cs.addMessage(See.only(this),
                    new ModelMessage(ModelMessage.MessageType.SONS_OF_LIBERTY,
                                     (newSoL > oldSoL)
                                     ? "model.player.SoLIncrease"
                                     : "model.player.SoLDecrease", this)
                              .addAmount("%oldSoL%", oldSoL)
                              .addAmount("%newSoL%", newSoL));
            }
            oldSoL = newSoL; // Remember SoL for check changes at next turn.
        }

        // Europe.
        if (europe != null) {
            ((ServerModelObject) europe).csNewTurn(random, cs);
        }
        // Units.
        for (Unit unit : new ArrayList<Unit>(getUnits())) {
            try {
                ((ServerModelObject) unit).csNewTurn(random, cs);
            } catch (ClassCastException e) {
                logger.log(Level.SEVERE, "Not a ServerUnit: " + unit.getId(), e);
            }
        }

        if (isEuropean()) { // Update liberty and immigration
            if (checkEmigrate()
                && !hasAbility("model.ability.selectRecruit")) {
                // Auto-emigrate if selection not allowed.
                csEmigrate(0, MigrationType.NORMAL, random, cs);
            } else {
                cs.addPartial(See.only(this), this, "immigration");
            }
            cs.addPartial(See.only(this), this, "liberty");

            if (getSpecification().getBoolean(GameOptions.ENABLE_UPKEEP)) {
                csPayUpkeep(random, cs);
            }

            int probability = getSpecification().getInteger(GameOptions.NATURAL_DISASTERS);
            if (probability > 0) {
                csNaturalDisasters(random, cs, probability);
            }

            if (getPlayerType() == PlayerType.REBEL
                && interventionBells >= getSpecification().getInteger("model.option.interventionBells")) {
                interventionBells = Integer.MIN_VALUE;
                // TODO: this assumes that the entry location will
                // always be a tile. This seems safe enough at the moment.
                Tile entryLocation = ((Tile) getEntryLocation()).getSafeTile(this, random);
                List<Unit> landUnits =
                    createUnits(getMonarch().getInterventionForce().getLandUnits(),
                                entryLocation);
                List<Unit> navalUnits =
                    createUnits(getMonarch().getInterventionForce().getNavalUnits(),
                                entryLocation);
                List<Unit> leftOver = loadShips(landUnits, navalUnits, random);
                for (Unit unit : leftOver) {
                    // no use for left over units
                    logger.warning("Disposing of left over unit " + unit);
                    unit.setLocation(null);
                    unit.dispose();
                }
                cs.add(See.perhaps(), entryLocation);
                cs.addMessage(See.only(this),
                              new ModelMessage(ModelMessage.MessageType.DEFAULT,
                                               "declareIndependence.interventionForceArrives",
                                               this));
            }
        }

        // Update stances
        while (!stanceDirty.isEmpty()) {
            ServerPlayer s = stanceDirty.remove(0);
            Stance sta = getStance(s);
            boolean war = sta == Stance.WAR;
            if (sta == Stance.UNCONTACTED) continue;
            for (Player p : getGame().getLiveEuropeanPlayers()) {
                ServerPlayer sp = (ServerPlayer) p;
                if (sp == this || p == s
                    || !p.hasContacted(this) || !p.hasContacted(p)) continue;
                if (p.hasAbility("model.ability.betterForeignAffairsReport")
                    || war) {
                    cs.addStance(See.only(sp), this, sta, s);
                    cs.addMessage(See.only(sp),
                        new ModelMessage(ModelMessage.MessageType.FOREIGN_DIPLOMACY,
                            "model.diplomacy." + sta + ".others", this)
                        .addStringTemplate("%attacker%", getNationName())
                        .addStringTemplate("%defender%", s.getNationName()));
                }
            }
        }
    }