private Map<Argument, Double> mStar(ArrayList<Argument> dialogue, int depth, Agent agent, Agent opponent, ArrayList<Argument> legalMoves){
		double playUtil=-9999; // player on turn's utility
		Map<Argument, Double> maxMoveMaxUtil = new HashMap<Argument, Double>();
		Map<Argument, Double> oppMoveOppUtil = new HashMap<Argument, Double>();
		Map<Argument, Double> proMoveProUtil = new HashMap<Argument, Double>();
		Argument maxMove = null; // move with maximised utility
		ArrayList<Argument> tempDialogue = new ArrayList<Argument>(); //secures the dialogue + M and dialogue +M +M' from paper
		if(legalMoves.isEmpty() 
				|| depth == 0){
			playUtil = evaluationFunction(dialogue, agent, opponent);
			maxMoveMaxUtil.put(null, playUtil);
		}
		else{
			double maxUtil = -999999;
			Host.populateArrayList(tempDialogue, dialogue);
			for(Argument move: legalMoves){
				legalMoves = findLegalmoves(agent, move, tempDialogue);
				if(depth==1){
					tempDialogue.add(move);
					playUtil = evaluationFunction(tempDialogue, agent, opponent);
				}
				else{
					tempDialogue.add(move);
					for(Agent agentOpp: agent.opp.keySet()){
						Argument oppMove;
						oppMoveOppUtil = mStar(tempDialogue, depth-1, agentOpp, agent, legalMoves);
						for(Argument key: oppMoveOppUtil.keySet()){
							oppMove = key;
							tempDialogue.add(oppMove);
							proMoveProUtil = mStar(tempDialogue, depth-2, agent, agentOpp, legalMoves);
							tempDialogue.remove(tempDialogue.get(tempDialogue.size()-1));
							for(Argument keyTwo: proMoveProUtil.keySet()){
								playUtil = proMoveProUtil.get(keyTwo);
								if(playUtil>maxUtil){ //might return more than one answer
									maxMoveMaxUtil.clear();
									maxUtil = playUtil;
									maxMove = move;
									maxMoveMaxUtil.put(maxMove, maxUtil);
								}
							}
						}
					}					
				}
				tempDialogue.remove(tempDialogue.size()-1);
				if(playUtil>maxUtil){
					maxMoveMaxUtil.clear();
					maxUtil = playUtil;
					maxMove = move;
					maxMoveMaxUtil.put(maxMove, maxUtil);
				}
			}
		}
		return maxMoveMaxUtil;
	}