private static Moves getBestAttackPlan(BotState state, Region opponentRegion, int minArmies, int maxArmies) {
		Moves out = new Moves();
		List<Region> sortedOwnedNeighbors = getOrderedListOfRegionsByIdleArmies(state,
				opponentRegion.getOwnedNeighbors(state));
		// Try to fulfill at least the minArmies constraint by attacking
		// with all neighboring territories and deploying. First deploy and then
		// pull in more territories.
		int attackedWithSoFar = 0;
		for (int i = 0; i < sortedOwnedNeighbors.size(); i++) {
			if (i == 0) {
				int neededDeployment = Math.max(0, maxArmies - sortedOwnedNeighbors.get(0).getIdleArmies());
				int totalDeployment = Math.min(neededDeployment, stillAvailableArmies);
				if (totalDeployment > 0) {
					out.totalDeployment += totalDeployment;
					out.armyPlacementMoves.add(new PlaceArmiesMove(state.getMyPlayerName(),
							sortedOwnedNeighbors.get(0), totalDeployment));
				}
				int attackingArmies = Math
						.min(maxArmies, sortedOwnedNeighbors.get(0).getIdleArmies() + totalDeployment);
				out.attackTransferMoves.add(new AttackTransferMove(state.getMyPlayerName(),
						sortedOwnedNeighbors.get(0), opponentRegion, attackingArmies));
				attackedWithSoFar += attackingArmies;

			} else {
				// i != 0
				int stillNeededArmies = maxArmies - attackedWithSoFar;
				if (stillNeededArmies > 0 && sortedOwnedNeighbors.get(i).getIdleArmies() > 1) {
					int newAttackingArmies = Math.min(stillNeededArmies, sortedOwnedNeighbors.get(i).getIdleArmies());
					out.attackTransferMoves.add(new AttackTransferMove(state.getMyPlayerName(), sortedOwnedNeighbors
							.get(i), opponentRegion, newAttackingArmies));
					attackedWithSoFar += newAttackingArmies;
				}
			}
		}
		// If the calculated attack plan satisfies the minArtmies constraint
		// then return him. Else return null.
		if (attackedWithSoFar >= minArmies) {
			MovesPerformer.performMoves(state, out);
			stillAvailableArmies -= out.totalDeployment;
			return out;
		} else {
			return new Moves();
		}

	}