Index: geniuswebcore/test/geniusweb/protocol/session/mopac/MOPACSettingsTest.py
===================================================================
--- geniuswebcore/test/geniusweb/protocol/session/mopac/MOPACSettingsTest.py	(revision 69)
+++ geniuswebcore/test/geniusweb/protocol/session/mopac/MOPACSettingsTest.py	(revision 69)
@@ -0,0 +1,131 @@
+import json
+from typing import List
+import unittest
+from unittest.mock import Mock
+
+from pyson.ObjectMapper import ObjectMapper
+from tudelft_utilities_logging.ReportToLogger import ReportToLogger
+from unitpy.GeneralTests import GeneralTests
+from uri.uri import URI
+
+from geniusweb.deadline.Deadline import Deadline
+from geniusweb.deadline.DeadlineRounds import DeadlineRounds
+from geniusweb.deadline.DeadlineTime import DeadlineTime
+from geniusweb.protocol.session.SessionSettings import SessionSettings
+from geniusweb.protocol.session.TeamInfo import TeamInfo
+from geniusweb.protocol.session.mopac.MOPACSettings import MOPACSettings
+from geniusweb.references.Parameters import Parameters
+from geniusweb.references.PartyRef import PartyRef
+from geniusweb.references.PartyWithParameters import PartyWithParameters
+from geniusweb.references.PartyWithProfile import PartyWithProfile
+from geniusweb.references.ProfileRef import ProfileRef
+from geniusweb.voting.votingevaluators.LargestAgreement import LargestAgreement
+
+
+def mockParty(partyname:str, params: Parameters) -> TeamInfo :
+	team = Mock(TeamInfo)
+	team.getSize = Mock(return_value=1)
+	pwithp = Mock(PartyWithParameters)
+	team.getParties = Mock(
+		return_value=[PartyWithProfile(pwithp, Mock(ProfileRef))])
+	team.__repr__=Mock(return_value=partyname) #type:ignore
+	pwithp.__repr__=Mock(return_value=partyname) #type:ignore
+	pwithp.getParameters = Mock(return_value=params)
+	return team;
+	
+	
+class MOPACSettingsTest (unittest.TestCase, GeneralTests[MOPACSettings]):
+
+	jackson = ObjectMapper()
+	noparams = Parameters()
+	partyprof1 = mockParty("party1", noparams)
+	partyprof2 = mockParty("party2", noparams)
+	partyprof3 = mockParty("party3", noparams)
+	participants2 = [partyprof1,partyprof2]
+	participants3 = [partyprof1, partyprof2,partyprof3]
+
+	ve = LargestAgreement()
+
+
+	serialized = "{\"MOPACSettings\":{\"participants\":[{\"TeamInfo\":{\"parties\":[{\"party\":{\"partyref\":\"http://party1\",\"parameters\":{}},\"profile\":\"http://profile1\"}]}},{\"TeamInfo\":{\"parties\":[{\"party\":{\"partyref\":\"http://party2\",\"parameters\":{}},\"profile\":\"http://profile2\"}]}}],\"deadline\":{\"DeadlineTime\":{\"durationms\":100}},\"votingevaluator\":{\"LargestAgreement\":{}}}}";
+	
+
+	def setUp(self):
+		self.deadline = Mock(DeadlineTime)
+		self.deadline2 = Mock(Deadline)
+		self.settings1 = MOPACSettings(self.participants2, self.deadline,self.ve)
+		self.settings1a = MOPACSettings(self.participants2, self.deadline, self.ve)
+		self.settings2 = MOPACSettings(self.participants3, self.deadline, self.ve)
+		self.settings3 = MOPACSettings(self.participants2,self.deadline2,self.ve)
+	
+		
+		self.deadline.getDuration = Mock(return_value=1000)
+		self.deadline.__repr__=Mock(return_value="deadline")
+		self.deadline2.__repr__=Mock(return_value="deadline2")
+
+		# SERIALIZABLE version with REAL objects. Still no workaround for
+		# this...
+		self.party1 = PartyWithParameters(
+				PartyRef(URI("http://party1")), Parameters())
+		self.profile1 = ProfileRef(URI("http://profile1"))
+		self.party2 = PartyWithParameters(
+				PartyRef(URI("http://party2")), Parameters())
+		self.profile2 = ProfileRef(URI("http://profile2"))
+		self.partywithprof1 = PartyWithProfile(self.party1, self.profile1);
+		self.partywithprof2 = PartyWithProfile(self.party2, self.profile2)
+		participants = [
+				TeamInfo([self.partywithprof1]),TeamInfo([self.partywithprof2])]
+
+		deadlinetime = DeadlineTime(100)
+		self.sersettings = MOPACSettings(participants, deadlinetime, self.ve)
+
+	def getGeneralTestData(self)-> List[List[MOPACSettings]] :
+		return [[self.settings1, self.settings1a],
+				[self.settings2], [self.settings3]]
+
+	def getGeneralTestStrings(self)-> List[str]:
+		return [
+				"MOPACSettings.*party1.*party2.*deadline.*LargestAgreement.*",
+				"MOPACSettings.*party1.*party2.*deadline.*LargestAgreement.*",
+				"MOPACSettings.*party1.*party2.*deadline2.*LargestAgreement.*"]
+
+	def testgetProtocolTest(self):
+		self.assertEqual("MOPAC", 
+			str(self.settings1.getProtocol(
+				ReportToLogger("test")).getRef().getURI()))
+
+	def testconstructorNoDeadlineTest(self):
+		self.assertRaises(ValueError, 
+			lambda:MOPACSettings(self.participants2, None, self.ve))
+
+	def testMaxRuntime(self):
+		self.deadline.getDuration=Mock(return_value=234)
+		self.assertEqual(0.234, self.settings1.getMaxRunTime())
+
+	def testMaxRuntimeRounds(self):
+		deadline = Mock(DeadlineRounds)
+		deadline.getDuration=Mock(return_value=12000)
+
+		settings = MOPACSettings(self.participants2, deadline, self.ve)
+
+		self.assertEqual(12, settings.getMaxRunTime())
+
+	def testDeserialize(self):
+		obj = self.jackson.parse(json.loads(self.serialized),
+				SessionSettings)
+		print(obj)
+		self.assertEqual(self.sersettings, obj);
+
+	def testSerialize(self):
+		string = self.jackson.toJson(self.sersettings)
+		print(string)
+		self.assertEqual(json.loads(self.serialized), string)
+
+	def testWith(self):
+		saop = MOPACSettings(self.participants2, self.deadline, self.ve)
+		saop2 = saop.With(self.partyprof3)
+		self.assertEqual(3, len(saop2.getTeams()))
+
+	def testGetAllParties(self):
+		self.assertEqual([self.partywithprof1, self.partywithprof2],
+				self.sersettings.getAllParties())
Index: geniuswebcore/test/geniusweb/protocol/session/mopac/MOPACStateTest.py
===================================================================
--- geniuswebcore/test/geniusweb/protocol/session/mopac/MOPACStateTest.py	(revision 69)
+++ geniuswebcore/test/geniusweb/protocol/session/mopac/MOPACStateTest.py	(revision 69)
@@ -0,0 +1,246 @@
+from datetime import datetime
+import json
+from typing import List
+import unittest
+from unittest.mock import Mock
+
+from pyson.ObjectMapper import ObjectMapper
+from unitpy.GeneralTests import GeneralTests
+
+from geniusweb.actions.Action import Action
+from geniusweb.actions.PartyId import PartyId
+from geniusweb.progress.Progress import Progress
+from geniusweb.progress.ProgressTime import ProgressTime
+from geniusweb.protocol.ProtocolException import ProtocolException
+from geniusweb.protocol.session.TeamInfo import TeamInfo
+from geniusweb.protocol.session.mopac.MOPACSettings import MOPACSettings
+from geniusweb.protocol.session.mopac.MOPACState import MOPACState
+from geniusweb.protocol.session.mopac.PartyStates import PartyStates
+from geniusweb.protocol.session.mopac.phase.OfferPhase import OfferPhase
+from geniusweb.protocol.session.mopac.phase.Phase import PHASE_MAXTIME, Phase, \
+	PHASE_MINTIME
+from geniusweb.references.Parameters import Parameters
+from geniusweb.references.PartyWithParameters import PartyWithParameters
+from geniusweb.references.PartyWithProfile import PartyWithProfile
+from geniusweb.references.ProfileRef import ProfileRef
+from geniusweb.voting.votingevaluators.LargestAgreement import LargestAgreement
+
+
+class MOPACStateTest (unittest.TestCase, GeneralTests[MOPACState]):
+	maxDiff=None
+	
+	NOW = datetime.fromtimestamp(1001/1000.)
+
+	jackson = ObjectMapper()
+
+	settings = Mock(MOPACSettings)
+
+	state = MOPACState(None,[],None, settings, {})
+
+	PARTY1 = PartyId("party1");
+	PARTY2 =  PartyId("party2")
+	PARTY3 =  PartyId("party3")
+
+
+	# copy from MopacSettingsTest. We need settings here but don't want to mock
+	# this large structure.
+	mopacsettingstr = "{\"MOPACSettings\":{\"participants\":[{\"TeamInfo\":{\"parties\":[{\"party\":{\"partyref\":\"http://party1\",\"parameters\":{}},\"profile\":\"http://profile1\"}]}},{\"TeamInfo\":{\"parties\":[{\"party\":{\"partyref\":\"http://party2\",\"parameters\":{}},\"profile\":\"http://profile2\"}]}}],\"deadline\":{\"DeadlineTime\":{\"durationms\":100}},\"votingevaluator\":{\"LargestAgreement\":{}}}}";
+	# create real objects for the GeneralTests and for serialization tests
+	progress1 = ProgressTime(100, NOW)
+	progress2 = ProgressTime(200, NOW)
+
+	
+	serialized = "{\"MOPACState\":{\"phase\":{\"OfferPhase\":{\"partyStates\":{\"powers\":{},\"notYetActed\":[],\"actions\":[],\"agreements\":{},\"walkedAway\":[],\"exceptions\":{}},\"deadline\":100,\"evaluator\":{\"LargestAgreement\":{}}}},\"actions\":[],\"progress\":{\"ProgressTime\":{\"duration\":100,\"start\":1001}},\"settings\":{\"MOPACSettings\":{\"participants\":[{\"TeamInfo\":{\"parties\":[{\"party\":{\"partyref\":\"http://party1\",\"parameters\":{}},\"profile\":\"http://profile1\"}]}},{\"TeamInfo\":{\"parties\":[{\"party\":{\"partyref\":\"http://party2\",\"parameters\":{}},\"profile\":\"http://profile2\"}]}}],\"deadline\":{\"DeadlineTime\":{\"durationms\":100}},\"votingevaluator\":{\"LargestAgreement\":{}}}},\"partyprofiles\":{}}}"
+
+	def setUp(self):
+		self.partyparams1 = Mock(PartyWithParameters)
+		self.profile1 = PartyWithProfile(self.partyparams1,Mock(ProfileRef))
+		self.partyStates = PartyStates({})
+		self.phase1 = OfferPhase(self.partyStates, 100, LargestAgreement())
+		self.phase2 = OfferPhase(self.partyStates, 200, LargestAgreement())
+		self.params1 = Parameters().With("power", 2);
+		self.partyparams1.getParameters=Mock(return_value=self.params1)
+
+		realsettings = self.jackson.parse(json.loads(self.mopacsettingstr),	MOPACSettings)
+		party = Mock(TeamInfo)
+		pwithp = Mock(PartyWithParameters)
+		pwithp.getParameters=Mock(return_value= Parameters())
+		party.getParties=Mock(
+			return_value=[PartyWithProfile(pwithp, Mock(ProfileRef))])
+		party.getSize=Mock(return_value=1)
+		realsettings2 = realsettings.With(party)
+
+		self.state1 = MOPACState(self.phase1, [], self.progress1, realsettings, {})
+		self.state1a = MOPACState(self.phase1, [], self.progress1, realsettings, {})
+		self.state2 = MOPACState(self.phase2, [], self.progress1, realsettings, {})
+		self.state3 = MOPACState(self.phase1, [Mock(Action)],
+				self.progress1, realsettings, {})
+		self.state4 = MOPACState(self.phase1, [], self.progress2,realsettings, {})
+		self.state5 = MOPACState(self.phase1, [], self.progress1,
+				realsettings2, {})
+		self.state6 = MOPACState(self.phase1, [], self.progress1,
+				realsettings,
+				{self.PARTY1: Mock(PartyWithProfile)})
+
+
+	def getGeneralTestData(self)-> List[List[MOPACState]] :
+		return [[self.state1, self.state1a],
+				[self.state2], [self.state3],
+				[self.state4], [self.state5],
+				[self.state6]]
+
+	def getGeneralTestStrings(self)-> List[str]:
+		return [
+				"MOPACState.*OfferPhase.*PartyStates.*,MOPACSettings.*PartyWithProfile.*ProgressTime.*",
+				"MOPACState.*OfferPhase.*PartyStates.*,MOPACSettings.*PartyWithProfile.*ProgressTime.*",
+				"MOPACState.*OfferPhase.*PartyStates.*,MOPACSettings.*PartyWithProfile.*ProgressTime.*",
+				"MOPACState.*OfferPhase.*PartyStates.*,MOPACSettings.*PartyWithProfile.*ProgressTime.*",
+				"MOPACState.*OfferPhase.*PartyStates.*,MOPACSettings.*PartyWithProfile.*ProgressTime.*",
+				"MOPACState.*OfferPhase.*PartyStates.*,MOPACSettings.*PartyWithProfile.*ProgressTime.*"]
+
+	def testsmokeTest(self):
+		pass
+
+	def testaddProfilesBeforeInit(self):
+		st = self.state.With(self.PARTY1, self.profile1)
+		self.assertTrue(self.PARTY1 in st.getPartyProfiles())
+
+	def testInit(self):
+		# no parties were added, should throw? Go to final mode?
+		# Notice that it's possible to create settings with 0 participants,
+		# because this is needed for Tournament mechanism.
+		state1 = self.state.initPhase(ProgressTime(100,datetime.fromtimestamp(0)),
+				1)
+		self.assertEqual(0, len(state1.getActions()))
+		self.assertEqual(0, len(state1.getAgreements().getMap()))
+		self.assertEqual(0, len(state1.getPartyProfiles()))
+		phase1 = state1.getPhase()
+		self.assertTrue(isinstance(phase1,OfferPhase))
+		offer1 = phase1
+		self.assertEqual(PartyStates({}), offer1.getPartyStates())
+	
+	def testgetAgreementsTest(self):
+		st = self.state.initPhase(ProgressTime(100, datetime.fromtimestamp(0)), 1)
+		self.assertEqual(0, len(st.getAgreements().getMap()))
+
+	def testDeserialize(self):
+		obj = self.jackson.parse(json.loads(self.serialized), MOPACState)
+		print(obj)
+		self.assertEqual(self.state1, obj)
+
+	def testSerialize(self):
+		jsonobj = self.jackson.toJson(self.state1)
+		print(jsonobj)
+		self.assertEqual(json.loads(self.serialized), jsonobj)
+
+	def testNewPhasePossible(self):
+		phase = Mock(Phase)
+		actions = []
+		progress = Mock(Progress)
+		progress.getTerminationTime=Mock(return_value=
+				datetime.fromtimestamp(PHASE_MAXTIME/1000.)) # plenty for new phase
+		def checkargs(*args, **kwargs):
+			if args[0]==10 + PHASE_MINTIME:
+				return False
+			raise ValueError("unexpected arg");
+			
+				
+		progress.isPastDeadline.side_effect=checkargs
+
+		partyprofiles = {}
+		s1 = MOPACState(phase, actions, progress, self.settings,
+				partyprofiles)
+
+		states = Mock(PartyStates)
+		phase.getPartyStates=Mock(return_value=states)
+		states.getNegotiatingParties=Mock(return_value=	
+						set([self.PARTY1, self.PARTY2]))
+		self.assertTrue(s1.isNewPhasePossible(10))
+
+	def testNewPhasePossibleOnly1Party(self):
+		phase = Mock(Phase)
+		actions = []
+		progress = Mock(Progress)
+		progress.getTerminationTime=Mock(
+				return_value=datetime.fromtimestamp(PHASE_MAXTIME/1000.)) 
+				# plenty for new phase
+				
+		def checkargs(*args, **kwargs):
+			if args[0]==10 + PHASE_MINTIME:
+				return False
+			raise ValueError("unexpected arg");
+			
+				
+		progress.isPastDeadline.side_effect=checkargs
+		
+		partyprofiles = {}
+		s1 = MOPACState(phase, actions, progress, self.settings,
+				partyprofiles)
+
+		states = Mock(PartyStates)
+		phase.getPartyStates=Mock(return_value=states)
+		states.getNegotiatingParties=Mock(return_value=
+				set([self.PARTY1]))
+		self.assertFalse(s1.isNewPhasePossible(10))
+
+	def testNewPhasePossibleNotEnoughTime(self):
+		phase = Mock(Phase)
+		actions = []
+		progress = Mock(Progress)
+		progress.getTerminationTime=Mock(
+				return_value=datetime.fromtimestamp((PHASE_MINTIME - 10)/1000.))
+		partyprofiles = {}
+		s1 = MOPACState(phase, actions, progress, self.settings,
+				partyprofiles)
+
+		states = Mock(PartyStates)
+		phase.getPartyStates=Mock(return_value=states)
+		states.getNegotiatingParties=Mock(return_value=
+				set([self.PARTY1]))
+		self.assertFalse(s1.isNewPhasePossible(10))
+
+	def testnextPhaseTest(self):
+		NOW = 102;
+		phase = Mock(Phase)
+		actions = []
+		progress = Mock(Progress)
+		progress.getTerminationTime=Mock(return_value=
+				datetime.fromtimestamp(PHASE_MAXTIME/1000.))
+		partyprofiles = {}
+		s1 = MOPACState(phase, actions, progress, self.settings,
+				partyprofiles)
+
+		# PhaseB is the next phase, with remaining time
+		phaseB = Mock(Phase)
+		
+		def checkargs(*args, **kwargs):
+			if args[0]==NOW and args[1]==PHASE_MAXTIME-NOW:
+				return phaseB
+			raise ValueError("unexpected args")
+		
+		phase.next.side_effect=checkargs
+		
+		s2 = s1.nextPhase(NOW)
+		self.assertEquals(phaseB, s2.getPhase())
+
+	def testexceptionTest(self):
+		phase = Mock(Phase)
+		actions = []
+		progress = Mock(Progress)
+		
+		partyprofiles = {}
+		s1 = MOPACState(phase, actions, progress, self.settings,
+				partyprofiles)
+
+		exphase = Mock(Phase); # supposed phase that contains the exception
+		
+		def checkargs(*args, **kwargs):
+			if isinstance(args[0], ProtocolException):
+				return exphase
+			raise ValueError("expected ProtocolException") 
+			
+		phase.WithException.side_effect=checkargs
+
+		errstate = s1.WithException(ProtocolException("test", self.PARTY1))
+		self.assertEqual(exphase, errstate.getPhase())
+		self.assertEqual(progress, errstate.getProgress())
Index: geniuswebcore/test/geniusweb/protocol/session/mopac/MOPACTest.py
===================================================================
--- geniuswebcore/test/geniusweb/protocol/session/mopac/MOPACTest.py	(revision 69)
+++ geniuswebcore/test/geniusweb/protocol/session/mopac/MOPACTest.py	(revision 69)
@@ -0,0 +1,189 @@
+from datetime import datetime
+import json
+import time
+import unittest
+from unittest.mock import Mock
+
+from pyson.ObjectMapper import ObjectMapper
+from tudelft.utilities.repository.NoResourcesNowException import NoResourcesNowException
+from tudelft_utilities_logging.Reporter import Reporter
+
+from geniusweb.actions.Offer import Offer
+from geniusweb.actions.PartyId import PartyId
+from geniusweb.inform.Inform import Inform
+from geniusweb.protocol.partyconnection.ProtocolToPartyConn import ProtocolToPartyConn
+from geniusweb.protocol.partyconnection.ProtocolToPartyConnFactory import ProtocolToPartyConnFactory
+from geniusweb.protocol.session.mopac.MOPAC import MOPAC
+from geniusweb.protocol.session.mopac.MOPACSettings import MOPACSettings
+from geniusweb.protocol.session.mopac.MOPACState import MOPACState
+from geniusweb.protocol.session.mopac.PartyStates import PartyStates
+from geniusweb.protocol.session.mopac.phase.OfferPhase import OfferPhase
+from geniusweb.protocol.session.mopac.phase.VotingPhase import VotingPhase
+
+
+class MOPACTest(unittest.TestCase):
+
+	jackson = ObjectMapper()
+
+	PARTY1ID = PartyId("party1")
+	PARTY2ID = PartyId("party2")
+	PARTY3ID = PartyId("party3")
+
+	# don't try to mock settings, all parts are needed and mocking
+	# makes the test unreadable.
+	setstr = "{\"MOPACSettings\":{\"participants\":[" +\
+			"{\"TeamInfo\":{\"parties\":[{\"party\":{\"partyref\":\"http://party1\",\"parameters\":{}},\"profile\":\"http://profile1\"}]}}," +\
+			"{\"TeamInfo\":{\"parties\":[{\"party\":{\"partyref\":\"http://party2\",\"parameters\":{}},\"profile\":\"http://profile2\"}]}}," +\
+			"{\"TeamInfo\":{\"parties\":[{\"party\":{\"partyref\":\"http://party3\",\"parameters\":{}},\"profile\":\"http://profile3\"}]}}]," +\
+			"\"deadline\":{\"DeadlineTime\":{\"durationms\":100}},\"votingevaluator\":{\"LargestAgreement\":{}}}}"
+
+	
+	logger = Mock(Reporter)
+	
+	factory = Mock(	ProtocolToPartyConnFactory)
+
+	
+	def setUp(self):
+		self.conn1 = Mock(ProtocolToPartyConn)
+		self.conn2 = Mock(ProtocolToPartyConn)
+		self.conn3 = Mock(ProtocolToPartyConn)
+
+		self.settings = self.jackson.parse(json.loads(self.setstr), MOPACSettings)
+		self.mopac = self.settings.getProtocol(self.logger)
+
+		self.connections = [self.conn1, self.conn2, self.conn3]
+		self.factory.connectAll=Mock(return_value=self.connections)
+
+		# hack the state.with(connection) stuff simplistically
+
+		self.conn1.getParty=Mock(return_value=self.PARTY1ID)
+		self.conn2.getParty=Mock(return_value=self.PARTY2ID)
+		self.conn3.getParty=Mock(return_value=self.PARTY3ID)
+
+	def testSmoke(self):
+		pass
+
+	def testGetDescr(self):
+		self.assertNotEqual(None, self.mopac.getDescription())
+
+	def testInitialState(self):
+		state = self.mopac.getState()
+		self.assertEqual(self.settings, state.getSettings())
+		self.assertEqual(0, len(state.getActions()))
+
+	def testProtocol(self):
+		self.assertEquals("MOPAC", str(self.mopac.getRef().getURI().getPath()))
+
+	def testWorkingCheckDeadline(self):
+		self.mopac.start(self.factory)
+
+		self.assertFalse(self.mopac.getState().isFinal(time.time()*1000))
+		# we have deadline in 100ms so check
+		time.sleep(200/1000)
+		self.assertTrue(self.mopac.getState().isFinal(time.time()*1000))
+
+	def testSubscribedToConnections(self):
+		self.mopac.start(self.factory)
+		
+		self.assertEquals(1, self.conn1.addListener.call_count)
+		self.assertEquals(1, self.conn2.addListener.call_count)
+		self.assertEquals(1, self.conn3.addListener.call_count)
+		
+
+	def testActionIsBroadcast(self):
+		self.mopac.start(self.factory)
+		offer = Mock(Offer)
+		self.mopac._actionRequest(self.conn1, offer, 1)
+
+		# 1 time for YourTurn, one time for ActionDone.
+		# but filtering ActionDone here (instead of Action) does not work,
+		# maybe bug in Mockito?
+		
+		self.assertEqual( 2, len([call for call in self.conn1.send.call_args_list
+			if isinstance(call[0][0], Inform)]))
+
+
+	#@Test(expected = RuntimeException.class)
+	def testPartyFailsConnect(self):
+		'''
+		Fatal error occurs, run should fail
+		'''
+		factory1 = Mock(ProtocolToPartyConnFactory)
+		# irrecoverable fail test
+		def doExc(conn):
+			raise ConnectionError("Failed to connect to parties")
+		
+		factory1.connectAll.side_effect=doExc
+	
+		self.assertRaises(ConnectionError, lambda:self.mopac.start(factory1))
+
+
+	callnr=0
+
+	def testPartyFailsConnect2ndtimeOK(self):
+		'''
+		Nonfatal error occurs, protocol should retry till success
+		'''
+		now = time.time()*1000
+		factory1 = Mock(ProtocolToPartyConnFactory)
+		# recoverable fail, and then success.
+		
+		this=self
+		def doExcThenOk(con): 
+			if this.callnr==0:
+				this.callnr=1
+				raise NoResourcesNowException("try again later",
+						datetime.fromtimestamp((now + 100)/1000.))
+			return this.connections
+
+		factory1.connectAll.side_effect=doExcThenOk
+		
+		self.mopac.start(factory1)
+
+	def testProceedsNextPhase(self):
+		'''
+		Test that in Offer phase, and party does action, the next phase is
+		entered.
+		'''
+		# the state before the last party makes the offer
+		offerstate = Mock(MOPACState)
+		offerstate.getSettings=Mock(return_value=self.settings)
+		offerphase = Mock(OfferPhase)
+		offerphase.isFinal=Mock(return_value=False)
+		offerstate.getPhase=Mock(return_value=offerphase)
+		offerstate.__repr__=Mock(return_value="offerstate")
+
+		# the phase where all parties placed an offer
+		finalofferphase = Mock(OfferPhase)
+		finalofferphase.isFinal=Mock(return_value=True)
+		finalofferstate = Mock(MOPACState)
+		finalofferstate.getPhase=Mock(return_value=finalofferphase)
+		finalofferstate.finishPhase=Mock(return_value=finalofferstate)
+		finalofferstate.__repr__=Mock(return_value="finalofferstate")
+		
+		#ADD
+		finalofferstate.isFinal = Mock(return_value=False)
+
+		offerstate.WithAction=Mock(return_value=finalofferstate)
+
+		# the phase where all parties can start voting.
+		# this is the state to be reached.
+		now = time.time()*1000
+		votingstate = Mock(MOPACState)
+		votingphase = Mock(VotingPhase)
+		votingpartystates = Mock(PartyStates)
+		votingpartystates.getNotYetActed=Mock(return_value=set())
+		votingphase.getDeadline=Mock(return_value=now + 100)
+		votingphase.getPartyStates=Mock(return_value=votingpartystates)
+		votingstate.getPhase=Mock(return_value=votingphase)
+		votingstate.__repr__=Mock(return_value="voringstate")
+
+		finalofferstate.nextPhase=Mock(return_value=votingstate)
+
+		mopac = MOPAC(offerstate, self.logger)
+		action = Mock(Offer)
+		mopac._actionRequest(self.conn3, action, now)
+
+		# check that the action result in reaching the voting phase
+		self.assertEqual(votingstate, mopac.getState())
+
Index: geniuswebcore/test/geniusweb/protocol/session/mopac/PartyStatesTest.py
===================================================================
--- geniuswebcore/test/geniusweb/protocol/session/mopac/PartyStatesTest.py	(revision 69)
+++ geniuswebcore/test/geniusweb/protocol/session/mopac/PartyStatesTest.py	(revision 69)
@@ -0,0 +1,77 @@
+import json
+from typing import List, Dict
+import unittest
+
+from pyson.ObjectMapper import ObjectMapper
+from unitpy.GeneralTests import GeneralTests
+
+from geniusweb.actions.PartyId import PartyId
+from geniusweb.inform.Agreements import Agreements
+from geniusweb.protocol.ProtocolException import ProtocolException
+from geniusweb.protocol.session.mopac.PartyStates import PartyStates
+
+
+class PartyStatesTest (unittest.TestCase, GeneralTests[PartyStates]):
+	jackson = ObjectMapper()
+
+	party1 = PartyId("party1")
+	party2 = PartyId("party2")
+	party3 = PartyId("party3")
+
+	powers:Dict[PartyId, int]  = {}
+	serialized = "{\"notYetActed\":[\"party2\",\"party1\",\"party3\"],\"actions\":[],\"agreements\":{},\"walkedAway\":[],\"exceptions\":{},\"powers\":{\"party2\":3,\"party1\":2,\"party3\":3}}";
+
+
+	powers[party1]= 2
+	powers[party2]=3
+	states2 = PartyStates(powers)
+	powers[party3]= 3
+	states1 = PartyStates(powers)
+	states1a = PartyStates(powers)
+
+	def getGeneralTestData(self)->List[List[PartyStates]] :
+		return [[self.states1, self.states1a],
+				[self.states2]]
+
+	def getGeneralTestStrings(self)->List[str] :
+		return [
+				"PartyStates.*\\[party., party., party.\\],\\[\\],Agreements\\{\\},\\[\\],\\{\\}.*",
+				"PartyStates.*\\[party., party.\\],\\[\\],Agreements\\{\\},\\[\\],\\{\\}.*"]
+
+	def testBasics(self):
+		self.assertEqual(self.powers.keys(), self.states1.getNegotiatingParties())
+		self.assertEqual(self.powers.keys(), self.states1.getNotYetActed());
+		self.assertEqual(0, len(self.states1.getExceptions()))
+
+	def  testException(self):
+		newstates = self.states1\
+			.WithException(ProtocolException("bla", self.party1))
+		self.assertEqual(Agreements(), newstates.getAgreements())
+		self.assertEqual(self.powers.keys(), self.states1.getNegotiatingParties())
+		self.assertEqual(set([self.party2, self.party3]),
+				newstates.getNotYetActed())
+
+	def testFinish(self):
+		newstates = self.states1.finish()
+		self.assertEqual(Agreements(), newstates.getAgreements())
+		self.assertEqual(self.powers.keys(), self.states1.getNegotiatingParties())
+		self.assertEqual(set(), newstates.getNotYetActed())
+
+	def testDeserialize(self):
+		obj = self.jackson.parse(json.loads(self.serialized), PartyStates)
+		print(obj)
+		self.assertEqual(self.states1, obj)
+
+	def testSerialize(self):
+		jsonobj = self.jackson.toJson(self.states1)
+		print(jsonobj);
+		jsonloads=json.loads(self.serialized)
+		# BRUTE HACK workaround set ordering
+		jsonloads['notYetActed']=jsonobj['notYetActed']
+		self.assertEqual(jsonloads, jsonobj)
+
+	def testWalkAway(self):
+		walkawaystate = self.states1.WithWalkAway(self.party2)
+		self.assertEqual(set([self.party1, self.party3]),
+				walkawaystate.getNotYetActed())
+		self.assertEqual([self.party2], walkawaystate.getWalkedAway())
Index: geniuswebcore/test/geniusweb/protocol/session/mopac/phase/OfferPhaseTest.py
===================================================================
--- geniuswebcore/test/geniusweb/protocol/session/mopac/phase/OfferPhaseTest.py	(revision 69)
+++ geniuswebcore/test/geniusweb/protocol/session/mopac/phase/OfferPhaseTest.py	(revision 69)
@@ -0,0 +1,203 @@
+import json
+from typing import List, Dict
+import unittest
+from unittest.mock import Mock
+
+from pyson.ObjectMapper import ObjectMapper
+from unitpy.GeneralTests import GeneralTests
+
+from geniusweb.actions.Accept import Accept
+from geniusweb.actions.EndNegotiation import EndNegotiation
+from geniusweb.actions.Offer import Offer
+from geniusweb.actions.PartyId import PartyId
+from geniusweb.actions.Votes import Votes
+from geniusweb.inform.YourTurn import YourTurn
+from geniusweb.issuevalue.Bid import Bid
+from geniusweb.issuevalue.DiscreteValue import DiscreteValue
+from geniusweb.protocol.ProtocolException import ProtocolException
+from geniusweb.protocol.session.mopac.PartyStates import PartyStates
+from geniusweb.protocol.session.mopac.phase.OfferPhase import OfferPhase
+from geniusweb.protocol.session.mopac.phase.Phase import Phase, PHASE_MINTIME
+from geniusweb.protocol.session.mopac.phase.VotingPhase import VotingPhase
+from geniusweb.voting.votingevaluators.LargestAgreement import LargestAgreement
+from geniusweb.voting.votingevaluators.LargestAgreementsLoop import LargestAgreementsLoop
+
+
+class OfferPhaseTest(unittest.TestCase, GeneralTests[OfferPhase]):
+	'''
+	We also test defaultPhase here.
+	'''
+	maxDiff=None
+	
+	jackson = ObjectMapper()
+
+	DEADLINE = 10
+	party1 = PartyId("party1")
+	party2 = PartyId("party2")
+	party3 = PartyId("party3")
+
+	powers:Dict[PartyId, int] = {}
+	evaluator = LargestAgreement()
+	evaluator2 = LargestAgreementsLoop()
+	
+	# just a test bid
+	bid = Bid({"issue": DiscreteValue("yes")})
+	offer = Offer(party1, bid)
+
+	serialized = "{\"OfferPhase\":{\"partyStates\":{\"powers\":{\"party2\":3,\"party1\":2,\"party3\":3},\"notYetActed\":[\"party2\",\"party1\",\"party3\"],\"actions\":[],\"agreements\":{},\"walkedAway\":[],\"exceptions\":{}},\"deadline\":10,\"evaluator\":{\"LargestAgreement\":{}}}}"
+
+	powers[party1]= 2
+	powers[party2]= 3
+	states2 = PartyStates(powers)
+	powers[party3]= 3
+	states = PartyStates(powers);
+	phase = OfferPhase(states, DEADLINE, evaluator)
+
+	phase1 = OfferPhase(states, 10, evaluator)
+	phase1a =OfferPhase(states, 10, evaluator)
+	phase2 = OfferPhase(states2, 10, evaluator)
+	phase3 = OfferPhase(states, 20, evaluator)
+	phase4 = OfferPhase(states, 10, evaluator2)
+
+	def getGeneralTestData(self)->List[List[OfferPhase]] :
+		return [[self.phase1, self.phase1a],
+				[self.phase2], [self.phase3],
+				[self.phase4]]
+
+	def getGeneralTestStrings(self)->List[str] :
+		return [
+				"OfferPhase.*PartyStates.*party., party., party..*\\[\\],Agreements.*\\[\\],\\{\\}.*],10,LargestAgreement.*",
+				"OfferPhase.*PartyStates.*party., party..*\\[\\],Agreements.*\\[\\],\\{\\}.*],10,LargestAgreement.*",
+				"OfferPhase.*PartyStates.*party., party., party.*\\[\\],Agreements.*\\[\\],\\{\\}.*],20,LargestAgreement.*",
+				"OfferPhase.*PartyStates.*party., party., party..*\\[\\],Agreements.*\\[\\],\\{\\}.*],10,LargestAgreementsLoop.*"]
+
+	def testsmokeTest(self) :
+		pass
+	
+	def testInitState(self):
+		self.assertEqual(3, len(self.phase.getPartyStates().getNotYetActed()))
+
+	def testInform(self):
+		self.assertEqual(YourTurn(), self.phase.getInform())
+
+	def testisFinalTest(self):
+		self.assertFalse(self.phase.isFinal(1))
+		self.assertTrue(self.phase.isFinal(10))
+
+	def testisFinalTestActorNotYetActed(self):
+		actedstate = Mock(PartyStates)
+		actedstate.getNotYetActed=Mock(return_value=set([self.party1]))
+		testphase = OfferPhase(actedstate, 10, self.evaluator)
+		self.assertFalse(testphase.isFinal(1))
+
+	def testisFinalTestAllActorsActed(self):
+		actedstate = Mock(PartyStates)
+		actedstate.getNotYetActed=Mock(return_value=set())
+		testphase = OfferPhase(actedstate, 10, self.evaluator)
+		self.assertTrue(testphase.isFinal(1))
+
+	def testcheckIncorrectActorTest(self):
+		self.assertRaises(ProtocolException, lambda:
+			self.phase._checkAction(self.party1, EndNegotiation(self.party2), 1))
+
+	def testcheckNotAllowedActionTest(self):
+		self.assertRaises(ProtocolException, lambda:
+			self.phase._checkAction(self.party1, Votes(self.party2,set()), 1))
+
+	def testException(self):
+		newphase = self.phase.WithException(ProtocolException("bla", self.party1))
+		self.assertEqual(10, newphase.getDeadline())
+		self.assertEqual(0, len(self.phase.getPartyStates().getActions()))
+
+	def testFinish(self):
+		ph = self.phase.finish()
+		self.assertEqual(0, len(ph.getPartyStates().getNotYetActed()))
+		self.assertEquals(3, len(ph.getPartyStates().getExceptions()))
+		self.assertEqual(0, len(self.phase.getPartyStates().getAgreements().getMap()))
+
+	def testNextWrong(self):
+		# state is not final, should not work
+		self.assertRaises(ValueError, lambda:self.phase.next(1, 1000))
+
+	def testNextNoParties(self):
+		ph = self.phase.finish()
+		# no parties are left now, all failed
+		# but this is not part of the next() check.
+		next = ph.next(1, 1000)
+		self.assertTrue(isinstance(next, VotingPhase))
+		# no remaining parties, since finish kicked all
+		self.assertEqual(0, len(next.getPartyStates().getNotYetActed()))
+
+	def testAllowed(self):
+		self.phase.With(self.party1, self.offer, 1)
+
+	def testAllowedWrongClass(self):
+		try:
+			self.phase._checkAction(self.party1, Accept(self.party1, self.bid), 1)
+		except ProtocolException as e:
+			self.assertTrue("not allowed in OfferPhase" in e.args[0])
+			return
+		self.fail("checkAction did not throw as expected")
+
+	def testAllowedWrongActor(self):
+		try:
+			self.phase._checkAction(self.party1, Accept(self.party2, self.bid), 1)
+		except ProtocolException as e:
+			self.assertTrue("Incorrect actor info in action" in e.args[0])
+			return
+		self.fail("checkAction did not throw as expected")
+
+	def testAllowedActorAlreadyActed(self):
+		testphase = self.phase.With(self.party1, self.offer, 1)
+		try:
+			testphase._checkAction(self.party1, self.offer, 2)
+		except ProtocolException  as e:
+			self.assertTrue("can not act anymore" in e.args[0])
+			return
+		self.fail("checkAction did not throw as expected")
+
+	def testAllowedActorAlreadyActed1(self):
+		# as theoprevious test, but using with() instead of checkAction
+		testphase = self.phase.With(self.party1, self.offer, 1)
+
+		newphase = testphase.With(self.party1, self.offer, 2)
+		# the party must remain as acted, because we can't retract his
+		# action...
+		self.assertEqual(1, len(newphase.getPartyStates().getActions()))
+		self.assertEqual(self.offer, newphase.getPartyStates().getActions()[0])
+		self.assertFalse(self.party1 in 
+				newphase.getPartyStates().getExceptions())
+
+	def testAllowedActingTooLate(self):
+		try:
+			self.phase._checkAction(self.party1, self.offer, self.DEADLINE + 1)
+		except ProtocolException as e:
+			self.assertTrue("passed deadline" in e.args[0])
+			return
+		self.fail("checkAction did not throw as expected")
+
+	def testgetOffersTest(self) :
+		self.assertEquals([], self.phase._getOffers())
+		offs = self.phase.With(self.party1, self.offer, 1)._getOffers()
+		self.assertEqual(1, len(offs))
+		self.assertEquals(self.bid, offs[0].getBid())
+
+	def testNextTooShortDuration(self):
+		self.assertRaises(ValueError, lambda:self.phase.next(1, PHASE_MINTIME - 1))
+
+	def testNextNotFinished(self):
+		self.assertRaises(ValueError, lambda:self.phase.next(1, PHASE_MINTIME + 1))
+
+	def testNext(self):
+		self.assertRaises(ValueError, lambda:self.phase.next(11, PHASE_MINTIME + 1))
+
+	def testDeserialize(self):
+		obj = self.jackson.parse(json.loads(self.serialized), Phase)
+		print(obj)
+		self.assertEqual(self.phase1, obj)
+
+	def testSerialize(self):
+		jsonobj = self.jackson.toJson(self.phase1)
+		print(jsonobj);
+		#FIXME how can we test this. The order of the notYetActed set is randomizing
+		#self.assertEqual(json.loads(self.serialized), jsonobj)
Index: geniuswebcore/test/geniusweb/protocol/session/mopac/phase/OptInPhaseTest.py
===================================================================
--- geniuswebcore/test/geniusweb/protocol/session/mopac/phase/OptInPhaseTest.py	(revision 69)
+++ geniuswebcore/test/geniusweb/protocol/session/mopac/phase/OptInPhaseTest.py	(revision 69)
@@ -0,0 +1,173 @@
+import json
+from typing import List, Dict
+import unittest
+from unittest.mock import Mock
+
+from pyson.ObjectMapper import ObjectMapper
+from unitpy.GeneralTests import GeneralTests
+
+from geniusweb.actions.EndNegotiation import EndNegotiation
+from geniusweb.actions.PartyId import PartyId
+from geniusweb.actions.Vote import Vote
+from geniusweb.actions.Votes import Votes
+from geniusweb.inform.OptIn import OptIn
+from geniusweb.issuevalue.Bid import Bid
+from geniusweb.issuevalue.DiscreteValue import DiscreteValue
+from geniusweb.protocol.ProtocolException import ProtocolException
+from geniusweb.protocol.session.mopac.PartyStates import PartyStates
+from geniusweb.protocol.session.mopac.phase.OfferPhase import OfferPhase
+from geniusweb.protocol.session.mopac.phase.OptInPhase import OptInPhase
+from geniusweb.protocol.session.mopac.phase.Phase import Phase, PHASE_MINTIME
+from geniusweb.voting.votingevaluators.LargestAgreement import LargestAgreement
+from geniusweb.voting.votingevaluators.LargestAgreementsLoop import LargestAgreementsLoop
+
+
+class OptInPhaseTest(unittest.TestCase, GeneralTests[OptInPhase]):
+	'''
+	We also test defaultPhase here.
+	'''
+	jackson = ObjectMapper()
+
+	DEADLINE = 10
+	party1 = PartyId("party1")
+	party2 = PartyId("party2")
+	party3 = PartyId("party3")
+
+
+	evaluator = LargestAgreement()
+	evaluator2 = LargestAgreementsLoop()
+
+	# just a test bid
+	bid = Bid({"issue":  DiscreteValue("yes")})
+	vote = Vote(party1, bid, 2, 3)
+	votes = Votes(party1, set([vote]))
+
+	prevVotes = [votes]
+
+	serialized = "{\"OptInPhase\":{\"votes\":[],\"partyStates\":{\"powers\":{\"party2\":3,\"party1\":2,\"party3\":3},\"notYetActed\":[\"party2\",\"party1\",\"party3\"],\"actions\":[],\"agreements\":{},\"walkedAway\":[],\"exceptions\":{}},\"deadline\":10,\"evaluator\":{\"LargestAgreement\":{}}}}"
+	
+	def setUp(self) :
+		self.powers:Dict[PartyId, int]  = {}
+		self.powers[self.party1]= 2
+		self.powers[self.party2]= 3
+		self.states2 = PartyStates(self.powers)
+		self.powers[self.party3]=3
+		self.states =  PartyStates(self.powers)
+
+		self.phase = OptInPhase(self.prevVotes, self.states, self.DEADLINE, self.evaluator)
+
+		# in these phases we just don't set prevPhase.
+		# this to avoid serialization troubles.
+		self.phase1 =  OptInPhase([], self.states, 10, self.evaluator)
+		self.phase1a =  OptInPhase([], self.states, 10, self.evaluator)
+		self.phase2 =  OptInPhase([], self.states2, 10, self.evaluator)
+		self.phase3 =  OptInPhase([], self.states, 20, self.evaluator)
+		self.phase4 =  OptInPhase([], self.states, 10, self.evaluator2)
+
+	def  getGeneralTestData(self)->List[List[OptInPhase]]:
+		return [[self.phase1, self.phase1a],
+				[self.phase2], [self.phase3],
+				[self.phase4]]
+
+
+	def  getGeneralTestStrings(self) ->List[str]:
+		return [
+				"OptInPhase.*PartyStates.*party., party., party..*\\[\\],Agreements.*\\[\\],\\{\\}.*],10,LargestAgreement.*",
+				"OptInPhase.*PartyStates.*party., party.*\\[\\],Agreements.*\\[\\],\\{\\}.*],10,LargestAgreement.*",
+				"OptInPhase.*PartyStates.*party., party., party..*\\[\\],Agreements.*\\[\\],\\{\\}.*],20,LargestAgreement.*",
+				"OptInPhase.*PartyStates.*party., party., party..*\\[\\],Agreements.*\\[\\],\\{\\}.*],10,LargestAgreementsLoop.*"]
+
+
+	def testsmokeTest(self):
+		pass
+
+	def testInitState(self):
+		self.assertEqual(3, len(self.phase.getPartyStates().getNotYetActed()))
+
+	def testInform(self) :
+		# when(prevPhase.getVotes()).thenReturn(Arrays.asList(votes));
+		self.assertEqual(OptIn([self.votes]), self.phase.getInform())
+
+	def testisFinalTest(self):
+		self.assertFalse(self.phase.isFinal(1))
+		self.assertTrue(self.phase.isFinal(10))
+
+	def testisFinalTestActorNotYetActed(self):
+		actedstate = Mock(PartyStates)
+		actedstate.getNotYetActed=Mock(return_value=set([self.party1]))
+		testphase =  OfferPhase(actedstate, 10, self.evaluator)
+		self.assertFalse(testphase.isFinal(1))
+
+	def testisFinalTestAllActorsActed(self):
+		actedstate = Mock(PartyStates)
+		actedstate.getNotYetActed=Mock(return_value=set([]))
+		testphase = OfferPhase(actedstate, 10, self.evaluator)
+		self.assertTrue(testphase.isFinal(1))
+
+	def testcheckIncorrectActorTest(self) :
+		self.assertRaises(ProtocolException, 
+			lambda:self.phase._checkAction(self.party1, EndNegotiation(self.party2), 1))
+
+	def testcheckNotAllowedActionTest(self) :
+		self.assertRaises(ProtocolException, lambda:self.phase._checkAction(self.party1, Votes(self.party2, set([])), 1))
+
+	def testFinish(self):
+		ph = self.phase.finish()
+		self.assertEqual(0,len(ph.getPartyStates().getNotYetActed()))
+		self.assertEqual(3, len(ph.getPartyStates().getExceptions()))
+		self.assertEqual(0,len(self.phase.getPartyStates().getAgreements().getMap()))
+	
+	def testNextWrong(self):
+		# state is not final, should not work
+		self.assertRaises(ValueError, lambda:self.phase.next(1, 1000))
+
+	def testNextNoParties(self) :
+		ph = self.phase.finish()
+		# no parties are left now, all failed
+		# but this is not part of the next() check.
+		next = ph.next(1, 1000)
+		self.assertTrue(isinstance(next, OfferPhase))
+		# no remaining parties, since finish kicked all
+		self.assertEqual(0, len(next.getPartyStates().getNotYetActed()))
+
+	def testAllowed(self):
+		# when(prevPhase.getVotes()).thenReturn(Arrays.asList(votes));
+		self.phase.With(self.party1, self.votes, 1)
+
+	def testAllowedNarrowingVote(self):
+		# the previous vote was maxPower=3,
+		# so this is an illegal narrowing of the previous vote
+		newVote = Vote(self.party1, self.bid, 2, 2)
+		newVotes = Votes(self.party1, set([newVote]))
+
+		# when(prevPhase.getVotes()).thenReturn(Arrays.asList(votes));
+
+		# check that party1 was kicked
+		newphase = self.phase.With(self.party1, newVotes, 1)
+		self.assertTrue(
+				self.party1 in newphase.getPartyStates().getExceptions())
+
+	def testNextTooShortDuration(self) :
+		self.assertRaises(ValueError, 
+			lambda:self.phase.next(1, PHASE_MINTIME - 1))
+		
+
+	def testNextNotFinished(self):
+		self.assertRaises(ValueError, 
+			lambda:self.phase.next(1, PHASE_MINTIME + 1))
+
+	def testNext(self):
+		self.assertRaises(ValueError, 
+			lambda:self.phase.next(11, PHASE_MINTIME + 1))
+
+	def testDeserialize(self):
+		obj = self.jackson.parse(json.loads(self.serialized), Phase)
+		print(obj)
+		self.assertEqual(self.phase1, obj)
+
+	def testSerialize(self):
+		jsonobj = self.jackson.toJson(self.phase1)
+		print(jsonobj);
+		#FIXME how can we test this. The order of the notYetActed set is randomizing
+		#self.assertEqual(json.loads(self.serialized), jsonobj)
+
Index: geniuswebcore/test/geniusweb/protocol/session/mopac/phase/VotingPhaseTest.py
===================================================================
--- geniuswebcore/test/geniusweb/protocol/session/mopac/phase/VotingPhaseTest.py	(revision 69)
+++ geniuswebcore/test/geniusweb/protocol/session/mopac/phase/VotingPhaseTest.py	(revision 69)
@@ -0,0 +1,166 @@
+import json
+from typing import List
+from unittest import mock
+import unittest
+from unittest.mock import Mock
+
+from pyson.ObjectMapper import ObjectMapper
+from unitpy.GeneralTests import GeneralTests
+
+from geniusweb.actions.EndNegotiation import EndNegotiation
+from geniusweb.actions.Offer import Offer
+from geniusweb.actions.PartyId import PartyId
+from geniusweb.actions.Vote import Vote
+from geniusweb.actions.Votes import Votes
+from geniusweb.inform.Voting import Voting
+from geniusweb.issuevalue.Bid import Bid
+from geniusweb.issuevalue.DiscreteValue import DiscreteValue
+from geniusweb.protocol.ProtocolException import ProtocolException
+from geniusweb.protocol.session.mopac.PartyStates import PartyStates
+from geniusweb.protocol.session.mopac.phase.OfferPhase import OfferPhase
+from geniusweb.protocol.session.mopac.phase.OptInPhase import OptInPhase
+from geniusweb.protocol.session.mopac.phase.Phase import PHASE_MINTIME, Phase
+from geniusweb.protocol.session.mopac.phase.VotingPhase import VotingPhase
+from geniusweb.voting.votingevaluators.LargestAgreement import LargestAgreement
+from geniusweb.voting.votingevaluators.LargestAgreementsLoop import LargestAgreementsLoop
+
+
+class VotingPhaseTest (unittest.TestCase, GeneralTests[VotingPhase]):
+	jackson = ObjectMapper()
+	'''
+	We also test defaultPhase here.
+	'''
+	DEADLINE = 10
+	party1 = PartyId("party1")
+	party2 = PartyId("party2")
+	party3 = PartyId("party3")
+
+	# private final OfferPhase prevPhase = mock(OfferPhase.class);
+
+	evaluator = LargestAgreement()
+	evaluator2 = LargestAgreementsLoop()
+	
+	# just a test bid
+	bid = Bid({"issue":  DiscreteValue("yes")})
+	vote = Vote(party1, bid, 2, 3);
+	votes = Votes(party1, set([vote]))
+
+	prevPhase = [ Offer(party1, bid)]
+
+	serialized = "{\"VotingPhase\":{\"offers\":[],\"partyStates\":{\"powers\":{\"party2\":3,\"party1\":2,\"party3\":3},\"notYetActed\":[\"party2\",\"party1\",\"party3\"],\"actions\":[],\"agreements\":{},\"walkedAway\":[],\"exceptions\":{}},\"deadline\":10,\"evaluator\":{\"LargestAgreement\":{}}}}"
+	
+	def setUp(self):
+		self.powers:Dict[PartyId, int]  = {}
+		self.powers[self.party1]=2
+		self.powers[self.party2]= 3
+		self.states2 = PartyStates(self.powers)
+		self.powers[self.party3]= 3
+		self.states = PartyStates(self.powers)
+
+		self.phase = VotingPhase(self.prevPhase, self.states, self.DEADLINE, self.evaluator)
+
+		# in these phases we just don't set prevPhase.
+		# this to avoid serialization troubles.
+		self.phase1 =  VotingPhase([], self.states, 10, self.evaluator);
+		self.phase1a =  VotingPhase([], self.states, 10, self.evaluator);
+		self.phase2 =  VotingPhase([], self.states2, 10, self.evaluator);
+		self.phase3 =  VotingPhase([], self.states, 20, self.evaluator);
+		self.phase4 =  VotingPhase([], self.states, 10, self.evaluator2);
+
+
+	def  getGeneralTestData(self)-> List[List[VotingPhase]]:
+		return [[self.phase1, self.phase1a],
+				[self.phase2], [self.phase3],
+				[self.phase4]]
+
+	def getGeneralTestStrings(self)->List[str] :
+		return [
+				"VotingPhase.*PartyStates.*party., party., party.*\\[\\],Agreements.*\\[\\],\\{\\}.*],10,LargestAgreement.*",
+				"VotingPhase.*PartyStates.*party., party.*\\[\\],Agreements.*\\[\\],\\{\\}.*],10,LargestAgreement.*",
+				"VotingPhase.*PartyStates.*party., party., party.*\\[\\],Agreements.*\\[\\],\\{\\}.*],20,LargestAgreement.*",
+				"VotingPhase.*PartyStates.*party., party., party.*\\[\\],Agreements.*\\[\\],\\{\\}.*],10,LargestAgreementsLoop.*"]
+
+	def testsmokeTest(self):
+		pass
+
+	def testInitState(self):
+		self.assertEqual(3, len(self.phase.getPartyStates().getNotYetActed()))
+
+	def testInform(self) :
+		# when(prevPhase.getOffers()).thenReturn(Arrays.asList(bid));
+		self.assertEqual(Voting([Offer(self.party1, self.bid)], self.powers),
+				self.phase.getInform())
+
+	def testisFinalTest(self):
+		self.assertFalse(self.phase.isFinal(1))
+		self.assertTrue(self.phase.isFinal(10))
+	
+	def testisFinalTestActorNotYetActed(self):
+		actedstate = Mock(PartyStates)
+		actedstate.getNotYetActed=Mock(return_value=set([self.party1]))
+		testphase = OfferPhase(actedstate, 10, self.evaluator)
+		self.assertFalse(testphase.isFinal(1))
+
+	def testisFinalTestAllActorsActed(self):
+		actedstate = Mock(PartyStates)
+		actedstate.getNotYetActed=Mock(return_value=set())
+		testphase = OfferPhase(actedstate, 10, self.evaluator)
+		self.assertTrue(testphase.isFinal(1))
+
+	def testcheckIncorrectActorTest(self) :
+		self.assertRaises(ProtocolException, 
+			lambda:self.phase._checkAction(self.party1, 
+								EndNegotiation(self.party2), 1))
+
+	def testcheckNotAllowedActionTest(self) :
+		self.assertRaises(ProtocolException, 
+			lambda:self.phase._checkAction(self.party1, Votes(self.party2, set()), 1))
+
+	def testFinish(self):
+		ph = self.phase.finish()
+		self.assertEqual(0, len(ph.getPartyStates().getNotYetActed()))
+		self.assertEquals(3, len(ph.getPartyStates().getExceptions()))
+		self.assertEqual(0, len(self.phase.getPartyStates().getAgreements().getMap()))
+
+	def testNextWrong(self):
+		# state is not final, should not work
+		self.assertRaises(ValueError, lambda:self.phase.next(1, 1000))
+
+	def testNextNoParties(self):
+		ph = self.phase.finish()
+		# no parties are left now, all failed
+		# but this is not part of the next() check.
+		next = ph.next(1, 1000)
+		self.assertTrue(isinstance(next, OptInPhase))
+		# no remaining parties, since finish kicked all
+		self.assertEqual(0, len(next.getPartyStates().getNotYetActed()))
+
+	def testAllowed(self):
+		self.phase.With(self.party1, self.votes, 1)
+
+	def testgetVotesTest(self):
+		self.assertEqual([], self.phase.getVotes())
+		vts = self.phase.With(self.party1, self.votes, 1).getVotes()
+		self.assertEquals([self.votes], vts)
+
+	def testNextTooShortDuration(self):
+		self.assertRaises(ValueError, 
+			lambda:self.phase.next(1, PHASE_MINTIME - 1))
+
+	def testNextNotFinished(self):
+		self.assertRaises(ValueError, lambda:self.phase.next(1, PHASE_MINTIME + 1))
+
+	def testNext(self):
+		self.assertRaises(ValueError, lambda:self.phase.next(11, PHASE_MINTIME + 1))
+
+
+	def testDeserialize(self):
+		obj = self.jackson.parse(json.loads(self.serialized), Phase)
+		print(obj)
+		self.assertEqual(self.phase1, obj)
+
+	def testSerialize(self):
+		jsonobj = self.jackson.toJson(self.phase1)
+		print(jsonobj);
+		#FIXME how can we test this. The order of the notYetActed set is randomizing
+		#self.assertEqual(json.loads(self.serialized), jsonobj)
