* @param unit The <code>Unit</code> to equip.
     * @param type The <code>EquipmentType</code> to equip with.
     * @param amount The change in the amount of equipment.
     * @return An <code>Element</code> encapsulating this action.
     */
    public Element equipUnit(ServerPlayer serverPlayer, Unit unit,
                             EquipmentType type, int amount) {
        Settlement settlement = (unit.getTile() == null) ? null
            : unit.getSettlement();
        GoodsContainer container = null;
        boolean tileDirty = false;
        if (unit.isInEurope()) {
            // Refuse to trade in boycotted goods
            for (AbstractGoods goods : type.getGoodsRequired()) {
                GoodsType goodsType = goods.getType();
                if (!serverPlayer.canTrade(goodsType)) {
                    return DOMMessage.clientError("No equip of " + type.getId()
                        + " due to boycott of " + goodsType.getId());
                }
            }
            // Will need a fake container to contain the goods to buy
            // in Europe.  Units may not necessarily have one.
            container = new GoodsContainer(getGame(), serverPlayer.getEurope());
        } else if (settlement != null) {
            // Equipping a unit at work in a colony should remove the unit
            // from the work location.
            if (unit.getLocation() instanceof WorkLocation) {
                unit.setLocation(settlement.getTile());
                tileDirty = true;
            }
            settlement.getGoodsContainer().saveState();
        }

        ChangeSet cs = new ChangeSet();
        List<EquipmentType> remove = null;
        // Process adding equipment first, so as to settle what has to
        // be removed.
        if (amount > 0) {
            for (AbstractGoods goods : type.getGoodsRequired()) {
                GoodsType goodsType = goods.getType();
                int n = amount * goods.getAmount();
                if (unit.isInEurope()) {
                    try {
                        serverPlayer.buy(container, goodsType, n, random);
                        serverPlayer.csFlushMarket(goodsType, cs);
                    } catch (IllegalStateException e) {
                        return DOMMessage.clientError(e.getMessage());
                    }
                } else if (settlement != null) {
                    if (settlement.getGoodsCount(goodsType) < n) {
                        return DOMMessage.clientError("Failed to equip: "
                            + unit.getId() + " not enough " + goodsType
                            + " in settlement " + settlement.getId());
                    }
                    settlement.removeGoods(goodsType, n);
                }
            }
            remove = unit.changeEquipment(type, amount);
            amount = 0; // 0 => all, now
        } else if (amount < 0) {
            remove = new ArrayList<EquipmentType>();
            remove.add(type);
            amount = -amount;
        } else {
            return null; // Nothing to do.
        }

        // Now do removal of equipment.
        ((ServerUnit)unit).csRemoveEquipment(settlement, remove, amount,
                                             random, cs);

        // Nothing for others to see except if the settlement population
        // changes.
        // If in Europe, we can get away with just updating the unit
        // as sell() will have added sales changes.  In a settlement,
        // the goods container will always be dirty, but the whole tile
        // will only need to be updated if the unit moved into it.
        if (unit.getInitialMovesLeft() != unit.getMovesLeft()) {
            unit.setMovesLeft(0);
        }
        if (unit.isInEurope()) {
            cs.add(See.only(serverPlayer), unit);
            cs.addPartial(See.only(serverPlayer), serverPlayer, "gold");
        } else if (settlement != null) {
            Unit carrier = unit.getCarrier();
            if (carrier != null
                && carrier.getInitialMovesLeft() != carrier.getMovesLeft()
                && carrier.getMovesLeft() != 0) {
                carrier.setMovesLeft(0);
                cs.add(See.only(serverPlayer), carrier);
            }
            if (tileDirty) {
                cs.add(See.perhaps(), settlement.getTile());
            } else {
                cs.add(See.only(serverPlayer), unit,
                       settlement.getGoodsContainer());
            }
        }
        return cs.build(serverPlayer);
    }