"""
Generated by Statechart compiler by Glenn De Jonghe and Joeri Exelmans

Date:   Tue Mar 15 15:48:55 2016

Model author: Yentl Van Tendeloo
Model name:   MvK Server
Model description:
Modelverse Kernel server. Server for the MvI, client of the MvS.
"""

from python_runtime.statecharts_core import *
import time
import os
import urllib
import sys
import json

from modelverse_kernel.main import ModelverseKernel

# package "MvK Server"

class MvKController(RuntimeClassBase):
	def __init__(self, controller, params):
		RuntimeClassBase.__init__(self, controller)
		
		self.semantics.big_step_maximality = StatechartSemantics.TakeMany
		self.semantics.internal_event_lifeline = StatechartSemantics.Queue
		self.semantics.input_event_lifeline = StatechartSemantics.FirstComboStep
		self.semantics.priority = StatechartSemantics.SourceParent
		self.semantics.concurrency = StatechartSemantics.Single
		
		# Call user defined constructor
		MvKController.user_defined_constructor(self, params)
	
	def user_defined_constructor(self, params):
		self.mvk = None
		self.users = []
		self.user_statecharts = {"__hierarchy": None}
		self.input_queue = []
		self.user_queue = {}
		self.source = None
		
		self.params = params
	
	def user_defined_destructor(self):
		pass
	
	def initializeStatechart(self):
		self.current_state[self.Root] = []
		self.current_state[self.Root_running] = []
		self.current_state[self.Root_running_wait_for_requests] = []
		self.current_state[self.Root_running_push] = []
		self.current_state[self.Root_running_find_users] = []
		
		# Enter default state
		self.enter_Root_init()
	
	# Unique IDs for all statechart nodes
	Root = 0
	Root_running = 1
	Root_running_wait_for_requests = 2
	Root_running_push = 3
	Root_running_find_users = 4
	Root_init = 5
	Root_get_root = 6
	Root_init_server = 7
	Root_init_executor = 8
	Root_running_wait_for_requests_wait = 9
	Root_running_push_wait = 10
	Root_running_push_process = 11
	Root_running_find_users_get_all_links = 12
	Root_running_find_users_retrieve_users = 13
	Root_running_find_users_got_usernames = 14
	Root_running_find_users_process_users = 15
	Root_running_find_users_creating_user = 16
	Root_running_find_users_wait = 17
	
	# Statechart enter/exit action method(s)
	
	def enter_Root_running(self):
		self.current_state[self.Root].append(self.Root_running)
	
	def exit_Root_running(self):
		self.exit_Root_running_wait_for_requests()
		self.exit_Root_running_push()
		self.exit_Root_running_find_users()
		self.current_state[self.Root] = []
	
	def enter_Root_running_wait_for_requests(self):
		self.current_state[self.Root_running].append(self.Root_running_wait_for_requests)
	
	def exit_Root_running_wait_for_requests(self):
		if self.Root_running_wait_for_requests_wait in self.current_state[self.Root_running_wait_for_requests]:
			self.exit_Root_running_wait_for_requests_wait()
		self.current_state[self.Root_running] = []
	
	def enter_Root_running_push(self):
		self.current_state[self.Root_running].append(self.Root_running_push)
	
	def exit_Root_running_push(self):
		if self.Root_running_push_wait in self.current_state[self.Root_running_push]:
			self.exit_Root_running_push_wait()
		if self.Root_running_push_process in self.current_state[self.Root_running_push]:
			self.exit_Root_running_push_process()
		self.current_state[self.Root_running] = []
	
	def enter_Root_running_find_users(self):
		self.current_state[self.Root_running].append(self.Root_running_find_users)
	
	def exit_Root_running_find_users(self):
		if self.Root_running_find_users_get_all_links in self.current_state[self.Root_running_find_users]:
			self.exit_Root_running_find_users_get_all_links()
		if self.Root_running_find_users_retrieve_users in self.current_state[self.Root_running_find_users]:
			self.exit_Root_running_find_users_retrieve_users()
		if self.Root_running_find_users_got_usernames in self.current_state[self.Root_running_find_users]:
			self.exit_Root_running_find_users_got_usernames()
		if self.Root_running_find_users_process_users in self.current_state[self.Root_running_find_users]:
			self.exit_Root_running_find_users_process_users()
		if self.Root_running_find_users_creating_user in self.current_state[self.Root_running_find_users]:
			self.exit_Root_running_find_users_creating_user()
		if self.Root_running_find_users_wait in self.current_state[self.Root_running_find_users]:
			self.exit_Root_running_find_users_wait()
		self.current_state[self.Root_running] = []
	
	def enter_Root_init(self):
		self.big_step.outputEventOM(Event("create_instance", None, [self, 'to_mvs', 'LocalMvS', self.params]))
		self.current_state[self.Root].append(self.Root_init)
	
	def exit_Root_init(self):
		self.current_state[self.Root] = []
	
	def enter_Root_get_root(self):
		self.current_state[self.Root].append(self.Root_get_root)
	
	def exit_Root_get_root(self):
		self.current_state[self.Root] = []
	
	def enter_Root_init_server(self):
		self.big_step.outputEventOM(Event("create_instance", None, [self, 'to_mvi', 'Server', '', 8001]))
		self.current_state[self.Root].append(self.Root_init_server)
	
	def exit_Root_init_server(self):
		self.current_state[self.Root] = []
	
	def enter_Root_init_executor(self):
		self.big_step.outputEventOM(Event("create_instance", None, [self, 'executor', 'Executor', self.mvk]))
		self.current_state[self.Root].append(self.Root_init_executor)
	
	def exit_Root_init_executor(self):
		self.current_state[self.Root] = []
	
	def enter_Root_running_wait_for_requests_wait(self):
		self.current_state[self.Root_running_wait_for_requests].append(self.Root_running_wait_for_requests_wait)
	
	def exit_Root_running_wait_for_requests_wait(self):
		self.current_state[self.Root_running_wait_for_requests] = []
	
	def enter_Root_running_push_wait(self):
		self.current_state[self.Root_running_push].append(self.Root_running_push_wait)
	
	def exit_Root_running_push_wait(self):
		self.current_state[self.Root_running_push] = []
	
	def enter_Root_running_push_process(self):
		self.current_state[self.Root_running_push].append(self.Root_running_push_process)
	
	def exit_Root_running_push_process(self):
		self.current_state[self.Root_running_push] = []
	
	def enter_Root_running_find_users_get_all_links(self):
		self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'to_mvs', Event("HTTP_input", None, ['requests=%s' % json.dumps([['RDK', [self.mvk.root]]]), 'parent'])]))
		self.current_state[self.Root_running_find_users].append(self.Root_running_find_users_get_all_links)
	
	def exit_Root_running_find_users_get_all_links(self):
		self.current_state[self.Root_running_find_users] = []
	
	def enter_Root_running_find_users_retrieve_users(self):
		self.current_state[self.Root_running_find_users].append(self.Root_running_find_users_retrieve_users)
	
	def exit_Root_running_find_users_retrieve_users(self):
		self.current_state[self.Root_running_find_users] = []
	
	def enter_Root_running_find_users_got_usernames(self):
		self.current_state[self.Root_running_find_users].append(self.Root_running_find_users_got_usernames)
	
	def exit_Root_running_find_users_got_usernames(self):
		self.current_state[self.Root_running_find_users] = []
	
	def enter_Root_running_find_users_process_users(self):
		self.current_state[self.Root_running_find_users].append(self.Root_running_find_users_process_users)
	
	def exit_Root_running_find_users_process_users(self):
		self.current_state[self.Root_running_find_users] = []
	
	def enter_Root_running_find_users_creating_user(self):
		self.current_state[self.Root_running_find_users].append(self.Root_running_find_users_creating_user)
	
	def exit_Root_running_find_users_creating_user(self):
		self.current_state[self.Root_running_find_users] = []
	
	def enter_Root_running_find_users_wait(self):
		self.timers[0] = 1.0
		self.current_state[self.Root_running_find_users].append(self.Root_running_find_users_wait)
	
	def exit_Root_running_find_users_wait(self):
		self.timers.pop(0, None)
		self.current_state[self.Root_running_find_users] = []
	
	# Statechart enter/exit default method(s)
	
	def enterDefault_Root_running(self):
		self.enter_Root_running()
		self.enterDefault_Root_running_wait_for_requests()
		self.enterDefault_Root_running_push()
		self.enterDefault_Root_running_find_users()
	
	def enterDefault_Root_running_wait_for_requests(self):
		self.enter_Root_running_wait_for_requests()
		self.enter_Root_running_wait_for_requests_wait()
	
	def enterDefault_Root_running_push(self):
		self.enter_Root_running_push()
		self.enter_Root_running_push_wait()
	
	def enterDefault_Root_running_find_users(self):
		self.enter_Root_running_find_users()
		self.enter_Root_running_find_users_get_all_links()
	
	# Statechart transitions
	
	def generateCandidatesChildren_Root(self):
		if self.current_state[self.Root][0] == self.Root_init:
			return self.generateCandidates_Root_init()
		elif self.current_state[self.Root][0] == self.Root_get_root:
			return self.generateCandidates_Root_get_root()
		elif self.current_state[self.Root][0] == self.Root_init_server:
			return self.generateCandidates_Root_init_server()
		elif self.current_state[self.Root][0] == self.Root_init_executor:
			return self.generateCandidates_Root_init_executor()
		elif self.current_state[self.Root][0] == self.Root_running:
			return self.generateCandidates_Root_running()
		return False
	
	def generateCandidates_Root(self):
		if not self.combo_step.isArenaChanged(self.Root):
			return self.generateCandidatesChildren_Root()
		else:
			return True
	
	def generateCandidatesCurrent_Root_init(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "instance_created":
				self.small_step.addCandidate(self.transition_Root_init_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_init(self):
		if not self.combo_step.isArenaChanged(self.Root_init):
			return self.generateCandidatesCurrent_Root_init()
		else:
			return True
	
	def transition_Root_init_1(self, parameters):
		instancename = parameters[0]
		self.exit_Root_init()
		self.big_step.outputEventOM(Event("start_instance", None, [self, instancename]))
		self.combo_step.setArenaChanged(self.Root)
		self.enter_Root_get_root()
	
	def generateCandidatesCurrent_Root_get_root(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "http_client_ready":
				self.small_step.addCandidate(self.transition_Root_get_root_1, e.parameters)
				return True
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "HTTP_output":
				self.small_step.addCandidate(self.transition_Root_get_root_2, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_get_root(self):
		if not self.combo_step.isArenaChanged(self.Root_get_root):
			return self.generateCandidatesCurrent_Root_get_root()
		else:
			return True
	
	def transition_Root_get_root_1(self, parameters):
		self.exit_Root_get_root()
		self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'to_mvs', Event("HTTP_input", None, ['requests=%s' % json.dumps([['RR', []]]), 'parent'])]))
		self.combo_step.setArenaChanged(self.Root)
		self.enter_Root_get_root()
	
	def transition_Root_get_root_2(self, parameters):
		data = parameters[0]
		self.exit_Root_get_root()
		self.mvk = ModelverseKernel(json.loads(data["data"])[0][0])
		self.mvk_next_op = "load_primitives"
		self.mvk_params = []
		self.combo_step.setArenaChanged(self.Root)
		self.enter_Root_init_server()
	
	def generateCandidatesCurrent_Root_init_server(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "instance_created":
				self.small_step.addCandidate(self.transition_Root_init_server_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_init_server(self):
		if not self.combo_step.isArenaChanged(self.Root_init_server):
			return self.generateCandidatesCurrent_Root_init_server()
		else:
			return True
	
	def transition_Root_init_server_1(self, parameters):
		instancename = parameters[0]
		self.exit_Root_init_server()
		self.big_step.outputEventOM(Event("start_instance", None, [self, instancename]))
		self.combo_step.setArenaChanged(self.Root)
		self.enter_Root_init_executor()
	
	def generateCandidatesCurrent_Root_init_executor(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "instance_created":
				self.small_step.addCandidate(self.transition_Root_init_executor_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_init_executor(self):
		if not self.combo_step.isArenaChanged(self.Root_init_executor):
			return self.generateCandidatesCurrent_Root_init_executor()
		else:
			return True
	
	def transition_Root_init_executor_1(self, parameters):
		instancename = parameters[0]
		self.exit_Root_init_executor()
		self.big_step.outputEventOM(Event("start_instance", None, [self, instancename]))
		self.combo_step.setArenaChanged(self.Root)
		self.enterDefault_Root_running()
	
	def generateCandidatesChildren_Root_running(self):
		branch_done = False
		branch_done = (self.generateCandidates_Root_running_wait_for_requests() or branch_done)
		branch_done = (self.generateCandidates_Root_running_push() or branch_done)
		branch_done = (self.generateCandidates_Root_running_find_users() or branch_done)
		return branch_done
	
	def generateCandidates_Root_running(self):
		if not self.combo_step.isArenaChanged(self.Root_running):
			return self.generateCandidatesChildren_Root_running()
		else:
			return True
	
	def generateCandidatesChildren_Root_running_wait_for_requests(self):
		if self.current_state[self.Root_running_wait_for_requests][0] == self.Root_running_wait_for_requests_wait:
			return self.generateCandidates_Root_running_wait_for_requests_wait()
		return False
	
	def generateCandidates_Root_running_wait_for_requests(self):
		if not self.combo_step.isArenaChanged(self.Root_running_wait_for_requests):
			return self.generateCandidatesChildren_Root_running_wait_for_requests()
		else:
			return True
	
	def generateCandidatesCurrent_Root_running_wait_for_requests_wait(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "from_mvi":
				self.small_step.addCandidate(self.transition_Root_running_wait_for_requests_wait_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_running_wait_for_requests_wait(self):
		if not self.combo_step.isArenaChanged(self.Root_running_wait_for_requests_wait):
			return self.generateCandidatesCurrent_Root_running_wait_for_requests_wait()
		else:
			return True
	
	def transition_Root_running_wait_for_requests_wait_1(self, parameters):
		source = parameters[0]
		data = parameters[1]
		self.exit_Root_running_wait_for_requests_wait()
		# No JSON encoding necessary, as it is not complex
		try:
		    if data["op"] == "set_input":
		        if data["element_type"] == "V":
		            value = json.loads(data["value"])
		        else:
		            value = data["value"]
		        args = (data["element_type"], value)
		        self.input_queue.append((source, "set_input", args, data["username"]))
		    elif data["op"] == "get_output":
		        args = []
		        self.input_queue.append((source, "get_output", args, data["username"]))
		    else:
		        print("DROPPING unknown operation: " + str(data["op"]))
		except:
		    import traceback
		    traceback.print_exc()
		    print("DROPPING deserialization error")
		    print("Decoding value " + str(data["value"]))
		self.combo_step.setArenaChanged(self.Root_running_wait_for_requests)
		self.enter_Root_running_wait_for_requests_wait()
	
	def generateCandidatesChildren_Root_running_push(self):
		if self.current_state[self.Root_running_push][0] == self.Root_running_push_wait:
			return self.generateCandidates_Root_running_push_wait()
		elif self.current_state[self.Root_running_push][0] == self.Root_running_push_process:
			return self.generateCandidates_Root_running_push_process()
		return False
	
	def generateCandidates_Root_running_push(self):
		if not self.combo_step.isArenaChanged(self.Root_running_push):
			return self.generateCandidatesChildren_Root_running_push()
		else:
			return True
	
	def generateCandidatesCurrent_Root_running_push_wait(self):
		enabled_events = self.getEnabledEvents()
		if self.input_queue and self.input_queue[0][3] in self.user_statecharts:
			self.small_step.addCandidate(self.transition_Root_running_push_wait_1, [])
			return True
		enabled_events = self.getEnabledEvents()
		if self.input_queue and self.input_queue[0][3] not in self.user_statecharts:
			self.small_step.addCandidate(self.transition_Root_running_push_wait_2, [])
			return True
		return False
	
	def generateCandidates_Root_running_push_wait(self):
		if not self.combo_step.isArenaChanged(self.Root_running_push_wait):
			return self.generateCandidatesCurrent_Root_running_push_wait()
		else:
			return True
	
	def transition_Root_running_push_wait_1(self, parameters):
		self.exit_Root_running_push_wait()
		self.combo_step.setArenaChanged(self.Root_running_push)
		self.enter_Root_running_push_process()
	
	def transition_Root_running_push_wait_2(self, parameters):
		self.exit_Root_running_push_wait()
		self.user_queue.setdefault(self.input_queue[0][3], []).append(self.input_queue.pop(0))
		self.raiseInternalEvent(Event("force_user_refresh", None, []))
		self.combo_step.setArenaChanged(self.Root_running_push)
		self.enter_Root_running_push_wait()
	
	def generateCandidatesCurrent_Root_running_push_process(self):
		enabled_events = self.getEnabledEvents()
		if self.input_queue[0][1] == 'set_input':
			self.small_step.addCandidate(self.transition_Root_running_push_process_1, [])
			return True
		enabled_events = self.getEnabledEvents()
		if self.input_queue[0][1] == 'get_output':
			self.small_step.addCandidate(self.transition_Root_running_push_process_2, [])
			return True
		return False
	
	def generateCandidates_Root_running_push_process(self):
		if not self.combo_step.isArenaChanged(self.Root_running_push_process):
			return self.generateCandidatesCurrent_Root_running_push_process()
		else:
			return True
	
	def transition_Root_running_push_process_1(self, parameters):
		self.exit_Root_running_push_process()
		source, op, args, username = self.input_queue.pop(0)
		self.big_step.outputEventOM(Event("narrow_cast", None, [self, self.user_statecharts[username], Event("set_input", None, [source, args])]))
		self.combo_step.setArenaChanged(self.Root_running_push)
		self.enter_Root_running_push_wait()
	
	def transition_Root_running_push_process_2(self, parameters):
		self.exit_Root_running_push_process()
		source, op, args, username = self.input_queue.pop(0)
		self.big_step.outputEventOM(Event("narrow_cast", None, [self, self.user_statecharts[username], Event("get_output", None, [source, args])]))
		self.combo_step.setArenaChanged(self.Root_running_push)
		self.enter_Root_running_push_wait()
	
	def generateCandidatesChildren_Root_running_find_users(self):
		if self.current_state[self.Root_running_find_users][0] == self.Root_running_find_users_get_all_links:
			return self.generateCandidates_Root_running_find_users_get_all_links()
		elif self.current_state[self.Root_running_find_users][0] == self.Root_running_find_users_retrieve_users:
			return self.generateCandidates_Root_running_find_users_retrieve_users()
		elif self.current_state[self.Root_running_find_users][0] == self.Root_running_find_users_got_usernames:
			return self.generateCandidates_Root_running_find_users_got_usernames()
		elif self.current_state[self.Root_running_find_users][0] == self.Root_running_find_users_process_users:
			return self.generateCandidates_Root_running_find_users_process_users()
		elif self.current_state[self.Root_running_find_users][0] == self.Root_running_find_users_creating_user:
			return self.generateCandidates_Root_running_find_users_creating_user()
		elif self.current_state[self.Root_running_find_users][0] == self.Root_running_find_users_wait:
			return self.generateCandidates_Root_running_find_users_wait()
		return False
	
	def generateCandidates_Root_running_find_users(self):
		if not self.combo_step.isArenaChanged(self.Root_running_find_users):
			return self.generateCandidatesChildren_Root_running_find_users()
		else:
			return True
	
	def generateCandidatesCurrent_Root_running_find_users_get_all_links(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "HTTP_output":
				self.small_step.addCandidate(self.transition_Root_running_find_users_get_all_links_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_running_find_users_get_all_links(self):
		if not self.combo_step.isArenaChanged(self.Root_running_find_users_get_all_links):
			return self.generateCandidatesCurrent_Root_running_find_users_get_all_links()
		else:
			return True
	
	def transition_Root_running_find_users_get_all_links_1(self, parameters):
		data = parameters[0]
		self.exit_Root_running_find_users_get_all_links()
		self.users = json.loads(data["data"])[0][0]
		self.combo_step.setArenaChanged(self.Root_running_find_users)
		self.enter_Root_running_find_users_retrieve_users()
	
	def generateCandidatesCurrent_Root_running_find_users_retrieve_users(self):
		enabled_events = self.getEnabledEvents()
		if self.users:
			self.small_step.addCandidate(self.transition_Root_running_find_users_retrieve_users_1, [])
			return True
		enabled_events = self.getEnabledEvents()
		if not self.users:
			self.small_step.addCandidate(self.transition_Root_running_find_users_retrieve_users_2, [])
			return True
		return False
	
	def generateCandidates_Root_running_find_users_retrieve_users(self):
		if not self.combo_step.isArenaChanged(self.Root_running_find_users_retrieve_users):
			return self.generateCandidatesCurrent_Root_running_find_users_retrieve_users()
		else:
			return True
	
	def transition_Root_running_find_users_retrieve_users_1(self, parameters):
		self.exit_Root_running_find_users_retrieve_users()
		self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'to_mvs', Event("HTTP_input", None, ['requests=%s' % json.dumps([['RV', [user]] for user in self.users]), 'parent'])]))
		self.combo_step.setArenaChanged(self.Root_running_find_users)
		self.enter_Root_running_find_users_got_usernames()
	
	def transition_Root_running_find_users_retrieve_users_2(self, parameters):
		self.exit_Root_running_find_users_retrieve_users()
		self.combo_step.setArenaChanged(self.Root_running_find_users)
		self.enter_Root_running_find_users_wait()
	
	def generateCandidatesCurrent_Root_running_find_users_got_usernames(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "HTTP_output":
				self.small_step.addCandidate(self.transition_Root_running_find_users_got_usernames_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_running_find_users_got_usernames(self):
		if not self.combo_step.isArenaChanged(self.Root_running_find_users_got_usernames):
			return self.generateCandidatesCurrent_Root_running_find_users_got_usernames()
		else:
			return True
	
	def transition_Root_running_find_users_got_usernames_1(self, parameters):
		data = parameters[0]
		self.exit_Root_running_find_users_got_usernames()
		self.users = [v[0] for v in json.loads(data["data"]) if v[0] not in self.user_statecharts]
		self.combo_step.setArenaChanged(self.Root_running_find_users)
		self.enter_Root_running_find_users_process_users()
	
	def generateCandidatesCurrent_Root_running_find_users_process_users(self):
		enabled_events = self.getEnabledEvents()
		if not self.users:
			self.small_step.addCandidate(self.transition_Root_running_find_users_process_users_1, [])
			return True
		enabled_events = self.getEnabledEvents()
		if self.users:
			self.small_step.addCandidate(self.transition_Root_running_find_users_process_users_2, [])
			return True
		return False
	
	def generateCandidates_Root_running_find_users_process_users(self):
		if not self.combo_step.isArenaChanged(self.Root_running_find_users_process_users):
			return self.generateCandidatesCurrent_Root_running_find_users_process_users()
		else:
			return True
	
	def transition_Root_running_find_users_process_users_1(self, parameters):
		self.exit_Root_running_find_users_process_users()
		self.combo_step.setArenaChanged(self.Root_running_find_users)
		self.enter_Root_running_find_users_wait()
	
	def transition_Root_running_find_users_process_users_2(self, parameters):
		self.exit_Root_running_find_users_process_users()
		self.big_step.outputEventOM(Event("create_instance", None, [self, 'users', 'UserStatechart', self.users[0]]))
		self.combo_step.setArenaChanged(self.Root_running_find_users)
		self.enter_Root_running_find_users_creating_user()
	
	def generateCandidatesCurrent_Root_running_find_users_creating_user(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "instance_created":
				self.small_step.addCandidate(self.transition_Root_running_find_users_creating_user_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_running_find_users_creating_user(self):
		if not self.combo_step.isArenaChanged(self.Root_running_find_users_creating_user):
			return self.generateCandidatesCurrent_Root_running_find_users_creating_user()
		else:
			return True
	
	def transition_Root_running_find_users_creating_user_1(self, parameters):
		instancename = parameters[0]
		self.exit_Root_running_find_users_creating_user()
		self.big_step.outputEventOM(Event("start_instance", None, [self, instancename]))
		self.big_step.outputEventOM(Event("narrow_cast", None, [self, instancename, Event("set_returnpath", None, [instancename])]))
		self.user_statecharts[self.users[0]] = instancename
		# Repush all this user's messages in the input queue
		self.input_queue.extend(self.user_queue.pop(self.users[0], []))
		self.users.pop(0)
		self.combo_step.setArenaChanged(self.Root_running_find_users)
		self.enter_Root_running_find_users_retrieve_users()
	
	def generateCandidatesCurrent_Root_running_find_users_wait(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "_0after":
				self.small_step.addCandidate(self.transition_Root_running_find_users_wait_1, e.parameters)
				return True
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "force_user_refresh":
				self.small_step.addCandidate(self.transition_Root_running_find_users_wait_2, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_running_find_users_wait(self):
		if not self.combo_step.isArenaChanged(self.Root_running_find_users_wait):
			return self.generateCandidatesCurrent_Root_running_find_users_wait()
		else:
			return True
	
	def transition_Root_running_find_users_wait_1(self, parameters):
		self.exit_Root_running_find_users_wait()
		self.combo_step.setArenaChanged(self.Root_running_find_users)
		self.enter_Root_running_find_users_get_all_links()
	
	def transition_Root_running_find_users_wait_2(self, parameters):
		self.exit_Root_running_find_users_wait()
		self.combo_step.setArenaChanged(self.Root_running_find_users)
		self.enter_Root_running_find_users_get_all_links()
	
	# Generate transition candidates for current small step
	def generateCandidates(self):
		self.generateCandidates_Root()

class Server(RuntimeClassBase):
	def __init__(self, controller, address, port):
		RuntimeClassBase.__init__(self, controller)
		
		self.semantics.big_step_maximality = StatechartSemantics.TakeMany
		self.semantics.internal_event_lifeline = StatechartSemantics.Queue
		self.semantics.input_event_lifeline = StatechartSemantics.FirstComboStep
		self.semantics.priority = StatechartSemantics.SourceParent
		self.semantics.concurrency = StatechartSemantics.Single
		
		# Call user defined constructor
		Server.user_defined_constructor(self, address, port)
	
	def user_defined_constructor(self, address, port):
		self.socket = None
		self.address = address
		self.port = port
	
	def user_defined_destructor(self):
		pass
	
	def initializeStatechart(self):
		self.current_state[self.Root] = []
		self.current_state[self.Root_main] = []
		self.current_state[self.Root_main_forward] = []
		self.current_state[self.Root_main_server] = []
		self.current_state[self.Root_main_close_socket] = []
		
		# Enter default state
		self.enterDefault_Root_main()
	
	# Unique IDs for all statechart nodes
	Root = 0
	Root_main = 1
	Root_main_forward = 2
	Root_main_server = 3
	Root_main_close_socket = 4
	Root_main_forward_forward = 5
	Root_main_server_init = 6
	Root_main_server_binding = 7
	Root_main_server_listening = 8
	Root_main_server_accepting = 9
	Root_main_close_socket_close = 10
	
	# Statechart enter/exit action method(s)
	
	def enter_Root_main(self):
		self.current_state[self.Root].append(self.Root_main)
	
	def exit_Root_main(self):
		self.exit_Root_main_forward()
		self.exit_Root_main_server()
		self.exit_Root_main_close_socket()
		self.current_state[self.Root] = []
	
	def enter_Root_main_forward(self):
		self.current_state[self.Root_main].append(self.Root_main_forward)
	
	def exit_Root_main_forward(self):
		if self.Root_main_forward_forward in self.current_state[self.Root_main_forward]:
			self.exit_Root_main_forward_forward()
		self.current_state[self.Root_main] = []
	
	def enter_Root_main_server(self):
		self.current_state[self.Root_main].append(self.Root_main_server)
	
	def exit_Root_main_server(self):
		if self.Root_main_server_init in self.current_state[self.Root_main_server]:
			self.exit_Root_main_server_init()
		if self.Root_main_server_binding in self.current_state[self.Root_main_server]:
			self.exit_Root_main_server_binding()
		if self.Root_main_server_listening in self.current_state[self.Root_main_server]:
			self.exit_Root_main_server_listening()
		if self.Root_main_server_accepting in self.current_state[self.Root_main_server]:
			self.exit_Root_main_server_accepting()
		self.current_state[self.Root_main] = []
	
	def enter_Root_main_close_socket(self):
		self.current_state[self.Root_main].append(self.Root_main_close_socket)
	
	def exit_Root_main_close_socket(self):
		if self.Root_main_close_socket_close in self.current_state[self.Root_main_close_socket]:
			self.exit_Root_main_close_socket_close()
		self.current_state[self.Root_main] = []
	
	def enter_Root_main_forward_forward(self):
		self.current_state[self.Root_main_forward].append(self.Root_main_forward_forward)
	
	def exit_Root_main_forward_forward(self):
		self.current_state[self.Root_main_forward] = []
	
	def enter_Root_main_server_init(self):
		self.big_step.outputEvent(Event("create_socket", "socket_out", []))
		self.current_state[self.Root_main_server].append(self.Root_main_server_init)
	
	def exit_Root_main_server_init(self):
		self.current_state[self.Root_main_server] = []
	
	def enter_Root_main_server_binding(self):
		self.big_step.outputEvent(Event("bind_socket", "socket_out", [self.socket, (self.address, self.port)]))
		self.current_state[self.Root_main_server].append(self.Root_main_server_binding)
	
	def exit_Root_main_server_binding(self):
		self.current_state[self.Root_main_server] = []
	
	def enter_Root_main_server_listening(self):
		self.big_step.outputEvent(Event("listen_socket", "socket_out", [self.socket]))
		self.current_state[self.Root_main_server].append(self.Root_main_server_listening)
	
	def exit_Root_main_server_listening(self):
		self.current_state[self.Root_main_server] = []
	
	def enter_Root_main_server_accepting(self):
		self.timers[0] = 1.0
		self.current_state[self.Root_main_server].append(self.Root_main_server_accepting)
	
	def exit_Root_main_server_accepting(self):
		self.timers.pop(0, None)
		self.current_state[self.Root_main_server] = []
	
	def enter_Root_main_close_socket_close(self):
		self.current_state[self.Root_main_close_socket].append(self.Root_main_close_socket_close)
	
	def exit_Root_main_close_socket_close(self):
		self.current_state[self.Root_main_close_socket] = []
	
	# Statechart enter/exit default method(s)
	
	def enterDefault_Root_main(self):
		self.enter_Root_main()
		self.enterDefault_Root_main_forward()
		self.enterDefault_Root_main_server()
		self.enterDefault_Root_main_close_socket()
	
	def enterDefault_Root_main_forward(self):
		self.enter_Root_main_forward()
		self.enter_Root_main_forward_forward()
	
	def enterDefault_Root_main_server(self):
		self.enter_Root_main_server()
		self.enter_Root_main_server_init()
	
	def enterDefault_Root_main_close_socket(self):
		self.enter_Root_main_close_socket()
		self.enter_Root_main_close_socket_close()
	
	# Statechart transitions
	
	def generateCandidatesChildren_Root(self):
		if self.current_state[self.Root][0] == self.Root_main:
			return self.generateCandidates_Root_main()
		return False
	
	def generateCandidates_Root(self):
		if not self.combo_step.isArenaChanged(self.Root):
			return self.generateCandidatesChildren_Root()
		else:
			return True
	
	def generateCandidatesChildren_Root_main(self):
		branch_done = False
		branch_done = (self.generateCandidates_Root_main_forward() or branch_done)
		branch_done = (self.generateCandidates_Root_main_server() or branch_done)
		branch_done = (self.generateCandidates_Root_main_close_socket() or branch_done)
		return branch_done
	
	def generateCandidates_Root_main(self):
		if not self.combo_step.isArenaChanged(self.Root_main):
			return self.generateCandidatesChildren_Root_main()
		else:
			return True
	
	def generateCandidatesChildren_Root_main_forward(self):
		if self.current_state[self.Root_main_forward][0] == self.Root_main_forward_forward:
			return self.generateCandidates_Root_main_forward_forward()
		return False
	
	def generateCandidates_Root_main_forward(self):
		if not self.combo_step.isArenaChanged(self.Root_main_forward):
			return self.generateCandidatesChildren_Root_main_forward()
		else:
			return True
	
	def generateCandidatesCurrent_Root_main_forward_forward(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "HTTP_output":
				self.small_step.addCandidate(self.transition_Root_main_forward_forward_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_main_forward_forward(self):
		if not self.combo_step.isArenaChanged(self.Root_main_forward_forward):
			return self.generateCandidatesCurrent_Root_main_forward_forward()
		else:
			return True
	
	def transition_Root_main_forward_forward_1(self, parameters):
		association_name = parameters[0]
		data = parameters[1]
		self.exit_Root_main_forward_forward()
		self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("from_mvi", None, [association_name, data])]))
		self.combo_step.setArenaChanged(self.Root_main_forward)
		self.enter_Root_main_forward_forward()
	
	def generateCandidatesChildren_Root_main_server(self):
		if self.current_state[self.Root_main_server][0] == self.Root_main_server_init:
			return self.generateCandidates_Root_main_server_init()
		elif self.current_state[self.Root_main_server][0] == self.Root_main_server_binding:
			return self.generateCandidates_Root_main_server_binding()
		elif self.current_state[self.Root_main_server][0] == self.Root_main_server_listening:
			return self.generateCandidates_Root_main_server_listening()
		elif self.current_state[self.Root_main_server][0] == self.Root_main_server_accepting:
			return self.generateCandidates_Root_main_server_accepting()
		return False
	
	def generateCandidates_Root_main_server(self):
		if not self.combo_step.isArenaChanged(self.Root_main_server):
			return self.generateCandidatesChildren_Root_main_server()
		else:
			return True
	
	def generateCandidatesCurrent_Root_main_server_init(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if (e.name == "created_socket") and (e.port == "socket_in"):
				self.small_step.addCandidate(self.transition_Root_main_server_init_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_main_server_init(self):
		if not self.combo_step.isArenaChanged(self.Root_main_server_init):
			return self.generateCandidatesCurrent_Root_main_server_init()
		else:
			return True
	
	def transition_Root_main_server_init_1(self, parameters):
		socket = parameters[0]
		self.exit_Root_main_server_init()
		self.socket = socket
		self.combo_step.setArenaChanged(self.Root_main_server)
		self.enter_Root_main_server_binding()
	
	def generateCandidatesCurrent_Root_main_server_binding(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if (e.name == "bound_socket") and (e.port == "socket_in"):
				parameters = e.parameters
				socket = parameters[0]
				if self.socket == socket:
					self.small_step.addCandidate(self.transition_Root_main_server_binding_1, e.parameters)
					return True
		return False
	
	def generateCandidates_Root_main_server_binding(self):
		if not self.combo_step.isArenaChanged(self.Root_main_server_binding):
			return self.generateCandidatesCurrent_Root_main_server_binding()
		else:
			return True
	
	def transition_Root_main_server_binding_1(self, parameters):
		socket = parameters[0]
		self.exit_Root_main_server_binding()
		self.combo_step.setArenaChanged(self.Root_main_server)
		self.enter_Root_main_server_listening()
	
	def generateCandidatesCurrent_Root_main_server_listening(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if (e.name == "listened_socket") and (e.port == "socket_in"):
				parameters = e.parameters
				socket = parameters[0]
				if self.socket == socket:
					self.small_step.addCandidate(self.transition_Root_main_server_listening_1, e.parameters)
					return True
		return False
	
	def generateCandidates_Root_main_server_listening(self):
		if not self.combo_step.isArenaChanged(self.Root_main_server_listening):
			return self.generateCandidatesCurrent_Root_main_server_listening()
		else:
			return True
	
	def transition_Root_main_server_listening_1(self, parameters):
		socket = parameters[0]
		self.exit_Root_main_server_listening()
		self.big_step.outputEvent(Event("accept_socket", "socket_out", [self.socket]))
		self.combo_step.setArenaChanged(self.Root_main_server)
		self.enter_Root_main_server_accepting()
	
	def generateCandidatesCurrent_Root_main_server_accepting(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if (e.name == "accepted_socket") and (e.port == "socket_in"):
				self.small_step.addCandidate(self.transition_Root_main_server_accepting_1, e.parameters)
				return True
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "instance_created":
				self.small_step.addCandidate(self.transition_Root_main_server_accepting_2, e.parameters)
				return True
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "_0after":
				self.small_step.addCandidate(self.transition_Root_main_server_accepting_3, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_main_server_accepting(self):
		if not self.combo_step.isArenaChanged(self.Root_main_server_accepting):
			return self.generateCandidatesCurrent_Root_main_server_accepting()
		else:
			return True
	
	def transition_Root_main_server_accepting_1(self, parameters):
		socket = parameters[0]
		connected_socket = parameters[1]
		self.exit_Root_main_server_accepting()
		self.big_step.outputEventOM(Event("create_instance", None, [self, 'sockets', 'Socket', connected_socket]))
		self.big_step.outputEvent(Event("accept_socket", "socket_out", [self.socket]))
		self.combo_step.setArenaChanged(self.Root_main_server)
		self.enter_Root_main_server_accepting()
	
	def transition_Root_main_server_accepting_2(self, parameters):
		instancename = parameters[0]
		self.exit_Root_main_server_accepting()
		self.big_step.outputEventOM(Event("start_instance", None, [self, instancename]))
		self.big_step.outputEventOM(Event("narrow_cast", None, [self, instancename, Event("set_association_name", None, [instancename])]))
		self.combo_step.setArenaChanged(self.Root_main_server)
		self.enter_Root_main_server_accepting()
	
	def transition_Root_main_server_accepting_3(self, parameters):
		self.exit_Root_main_server_accepting()
		self.combo_step.setArenaChanged(self.Root_main_server)
		self.enter_Root_main_server_accepting()
	
	def generateCandidatesChildren_Root_main_close_socket(self):
		if self.current_state[self.Root_main_close_socket][0] == self.Root_main_close_socket_close:
			return self.generateCandidates_Root_main_close_socket_close()
		return False
	
	def generateCandidates_Root_main_close_socket(self):
		if not self.combo_step.isArenaChanged(self.Root_main_close_socket):
			return self.generateCandidatesChildren_Root_main_close_socket()
		else:
			return True
	
	def generateCandidatesCurrent_Root_main_close_socket_close(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "close_socket":
				self.small_step.addCandidate(self.transition_Root_main_close_socket_close_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_main_close_socket_close(self):
		if not self.combo_step.isArenaChanged(self.Root_main_close_socket_close):
			return self.generateCandidatesCurrent_Root_main_close_socket_close()
		else:
			return True
	
	def transition_Root_main_close_socket_close_1(self, parameters):
		association_name = parameters[0]
		self.exit_Root_main_close_socket_close()
		self.big_step.outputEventOM(Event("delete_instance", None, [self, association_name]))
		self.combo_step.setArenaChanged(self.Root_main_close_socket)
		self.enter_Root_main_close_socket_close()
	
	# Generate transition candidates for current small step
	def generateCandidates(self):
		self.generateCandidates_Root()

class Socket(RuntimeClassBase):
	def __init__(self, controller, my_socket):
		RuntimeClassBase.__init__(self, controller)
		
		self.semantics.big_step_maximality = StatechartSemantics.TakeMany
		self.semantics.internal_event_lifeline = StatechartSemantics.Queue
		self.semantics.input_event_lifeline = StatechartSemantics.FirstComboStep
		self.semantics.priority = StatechartSemantics.SourceParent
		self.semantics.concurrency = StatechartSemantics.Single
		
		# Call user defined constructor
		Socket.user_defined_constructor(self, my_socket)
	
	def user_defined_constructor(self, my_socket):
		self.socket = my_socket
		self.received_data = ""
		self.send_data = ""
		self.closed = False
		self.association_name = None
	
	def user_defined_destructor(self):
		pass
	
	def initializeStatechart(self):
		self.current_state[self.Root] = []
		self.current_state[self.Root_connected] = []
		self.current_state[self.Root_connected_listening] = []
		self.current_state[self.Root_connected_sending] = []
		self.current_state[self.Root_connected_queueing] = []
		self.current_state[self.Root_connected_parsing] = []
		
		# Enter default state
		self.enter_Root_init()
	
	# Unique IDs for all statechart nodes
	Root = 0
	Root_connected = 1
	Root_connected_listening = 2
	Root_connected_sending = 3
	Root_connected_queueing = 4
	Root_connected_parsing = 5
	Root_init = 6
	Root_connected_listening_listen = 7
	Root_connected_listening_closed = 8
	Root_connected_sending_waiting_for_data = 9
	Root_connected_sending_transferring = 10
	Root_connected_queueing_queueing = 11
	Root_connected_parsing_wait_for_header = 12
	Root_connected_parsing_closing = 13
	Root_connected_parsing_wait_for_payload = 14
	Root_close = 15
	
	# Statechart enter/exit action method(s)
	
	def enter_Root_connected(self):
		self.current_state[self.Root].append(self.Root_connected)
	
	def exit_Root_connected(self):
		self.exit_Root_connected_listening()
		self.exit_Root_connected_sending()
		self.exit_Root_connected_queueing()
		self.exit_Root_connected_parsing()
		self.current_state[self.Root] = []
	
	def enter_Root_connected_listening(self):
		self.current_state[self.Root_connected].append(self.Root_connected_listening)
	
	def exit_Root_connected_listening(self):
		if self.Root_connected_listening_listen in self.current_state[self.Root_connected_listening]:
			self.exit_Root_connected_listening_listen()
		if self.Root_connected_listening_closed in self.current_state[self.Root_connected_listening]:
			self.exit_Root_connected_listening_closed()
		self.current_state[self.Root_connected] = []
	
	def enter_Root_connected_sending(self):
		self.current_state[self.Root_connected].append(self.Root_connected_sending)
	
	def exit_Root_connected_sending(self):
		if self.Root_connected_sending_waiting_for_data in self.current_state[self.Root_connected_sending]:
			self.exit_Root_connected_sending_waiting_for_data()
		if self.Root_connected_sending_transferring in self.current_state[self.Root_connected_sending]:
			self.exit_Root_connected_sending_transferring()
		self.current_state[self.Root_connected] = []
	
	def enter_Root_connected_queueing(self):
		self.current_state[self.Root_connected].append(self.Root_connected_queueing)
	
	def exit_Root_connected_queueing(self):
		if self.Root_connected_queueing_queueing in self.current_state[self.Root_connected_queueing]:
			self.exit_Root_connected_queueing_queueing()
		self.current_state[self.Root_connected] = []
	
	def enter_Root_connected_parsing(self):
		self.current_state[self.Root_connected].append(self.Root_connected_parsing)
	
	def exit_Root_connected_parsing(self):
		if self.Root_connected_parsing_wait_for_header in self.current_state[self.Root_connected_parsing]:
			self.exit_Root_connected_parsing_wait_for_header()
		if self.Root_connected_parsing_closing in self.current_state[self.Root_connected_parsing]:
			self.exit_Root_connected_parsing_closing()
		if self.Root_connected_parsing_wait_for_payload in self.current_state[self.Root_connected_parsing]:
			self.exit_Root_connected_parsing_wait_for_payload()
		self.current_state[self.Root_connected] = []
	
	def enter_Root_init(self):
		self.current_state[self.Root].append(self.Root_init)
	
	def exit_Root_init(self):
		self.current_state[self.Root] = []
	
	def enter_Root_connected_listening_listen(self):
		self.big_step.outputEvent(Event("recv_socket", "socket_out", [self.socket]))
		self.current_state[self.Root_connected_listening].append(self.Root_connected_listening_listen)
	
	def exit_Root_connected_listening_listen(self):
		self.current_state[self.Root_connected_listening] = []
	
	def enter_Root_connected_listening_closed(self):
		self.closed = True
		self.current_state[self.Root_connected_listening].append(self.Root_connected_listening_closed)
	
	def exit_Root_connected_listening_closed(self):
		self.current_state[self.Root_connected_listening] = []
	
	def enter_Root_connected_sending_waiting_for_data(self):
		self.current_state[self.Root_connected_sending].append(self.Root_connected_sending_waiting_for_data)
	
	def exit_Root_connected_sending_waiting_for_data(self):
		self.current_state[self.Root_connected_sending] = []
	
	def enter_Root_connected_sending_transferring(self):
		self.current_state[self.Root_connected_sending].append(self.Root_connected_sending_transferring)
	
	def exit_Root_connected_sending_transferring(self):
		self.current_state[self.Root_connected_sending] = []
	
	def enter_Root_connected_queueing_queueing(self):
		self.current_state[self.Root_connected_queueing].append(self.Root_connected_queueing_queueing)
	
	def exit_Root_connected_queueing_queueing(self):
		self.current_state[self.Root_connected_queueing] = []
	
	def enter_Root_connected_parsing_wait_for_header(self):
		self.current_state[self.Root_connected_parsing].append(self.Root_connected_parsing_wait_for_header)
	
	def exit_Root_connected_parsing_wait_for_header(self):
		self.current_state[self.Root_connected_parsing] = []
	
	def enter_Root_connected_parsing_closing(self):
		self.timers[0] = 0.0
		self.current_state[self.Root_connected_parsing].append(self.Root_connected_parsing_closing)
	
	def exit_Root_connected_parsing_closing(self):
		self.timers.pop(0, None)
		self.current_state[self.Root_connected_parsing] = []
	
	def enter_Root_connected_parsing_wait_for_payload(self):
		self.current_state[self.Root_connected_parsing].append(self.Root_connected_parsing_wait_for_payload)
	
	def exit_Root_connected_parsing_wait_for_payload(self):
		self.current_state[self.Root_connected_parsing] = []
	
	def enter_Root_close(self):
		self.big_step.outputEvent(Event("close_socket", "socket_out", [self.socket]))
		self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("close_socket", None, [self.association_name])]))
		self.current_state[self.Root].append(self.Root_close)
	
	def exit_Root_close(self):
		self.current_state[self.Root] = []
	
	# Statechart enter/exit default method(s)
	
	def enterDefault_Root_connected(self):
		self.enter_Root_connected()
		self.enterDefault_Root_connected_listening()
		self.enterDefault_Root_connected_sending()
		self.enterDefault_Root_connected_queueing()
		self.enterDefault_Root_connected_parsing()
	
	def enterDefault_Root_connected_listening(self):
		self.enter_Root_connected_listening()
		self.enter_Root_connected_listening_listen()
	
	def enterDefault_Root_connected_sending(self):
		self.enter_Root_connected_sending()
		self.enter_Root_connected_sending_waiting_for_data()
	
	def enterDefault_Root_connected_queueing(self):
		self.enter_Root_connected_queueing()
		self.enter_Root_connected_queueing_queueing()
	
	def enterDefault_Root_connected_parsing(self):
		self.enter_Root_connected_parsing()
		self.enter_Root_connected_parsing_wait_for_header()
	
	# Statechart transitions
	
	def generateCandidatesChildren_Root(self):
		if self.current_state[self.Root][0] == self.Root_init:
			return self.generateCandidates_Root_init()
		elif self.current_state[self.Root][0] == self.Root_connected:
			return self.generateCandidates_Root_connected()
		elif self.current_state[self.Root][0] == self.Root_close:
			return self.generateCandidates_Root_close()
		return False
	
	def generateCandidates_Root(self):
		if not self.combo_step.isArenaChanged(self.Root):
			return self.generateCandidatesChildren_Root()
		else:
			return True
	
	def generateCandidatesCurrent_Root_init(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "set_association_name":
				self.small_step.addCandidate(self.transition_Root_init_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_init(self):
		if not self.combo_step.isArenaChanged(self.Root_init):
			return self.generateCandidatesCurrent_Root_init()
		else:
			return True
	
	def transition_Root_init_1(self, parameters):
		association_name = parameters[0]
		self.exit_Root_init()
		self.association_name = association_name
		self.combo_step.setArenaChanged(self.Root)
		self.enterDefault_Root_connected()
	
	def generateCandidatesChildren_Root_connected(self):
		branch_done = False
		branch_done = (self.generateCandidates_Root_connected_listening() or branch_done)
		branch_done = (self.generateCandidates_Root_connected_sending() or branch_done)
		branch_done = (self.generateCandidates_Root_connected_queueing() or branch_done)
		branch_done = (self.generateCandidates_Root_connected_parsing() or branch_done)
		return branch_done
	
	def generateCandidatesCurrent_Root_connected(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "close":
				self.small_step.addCandidate(self.transition_Root_connected_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_connected(self):
		if not self.combo_step.isArenaChanged(self.Root_connected):
			branch_done = False
			if self.semantics.priority == StatechartSemantics.SourceParent:
				branch_done = self.generateCandidatesCurrent_Root_connected()
				if not branch_done:
					branch_done = self.generateCandidatesChildren_Root_connected()
			elif self.semantics.priority == StatechartSemantics.SourceChild:
				branch_done = self.generateCandidatesChildren_Root_connected()
				if not branch_done:
					branch_done = self.generateCandidatesCurrent_Root_connected()
			return branch_done
		else:
			return True
	
	def transition_Root_connected_1(self, parameters):
		self.exit_Root_connected()
		self.combo_step.setArenaChanged(self.Root)
		self.enter_Root_close()
	
	def generateCandidatesChildren_Root_connected_listening(self):
		if self.current_state[self.Root_connected_listening][0] == self.Root_connected_listening_listen:
			return self.generateCandidates_Root_connected_listening_listen()
		elif self.current_state[self.Root_connected_listening][0] == self.Root_connected_listening_closed:
			return self.generateCandidates_Root_connected_listening_closed()
		return False
	
	def generateCandidates_Root_connected_listening(self):
		if not self.combo_step.isArenaChanged(self.Root_connected_listening):
			return self.generateCandidatesChildren_Root_connected_listening()
		else:
			return True
	
	def generateCandidatesCurrent_Root_connected_listening_listen(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if (e.name == "received_socket") and (e.port == "socket_in"):
				parameters = e.parameters
				socket = parameters[0]
				data = parameters[1]
				if (self.socket == socket) and (len(data) > 0):
					self.small_step.addCandidate(self.transition_Root_connected_listening_listen_1, e.parameters)
					return True
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if (e.name == "received_socket") and (e.port == "socket_in"):
				parameters = e.parameters
				socket = parameters[0]
				data = parameters[1]
				if (self.socket == socket) and (len(data) == 0):
					self.small_step.addCandidate(self.transition_Root_connected_listening_listen_2, e.parameters)
					return True
		return False
	
	def generateCandidates_Root_connected_listening_listen(self):
		if not self.combo_step.isArenaChanged(self.Root_connected_listening_listen):
			return self.generateCandidatesCurrent_Root_connected_listening_listen()
		else:
			return True
	
	def transition_Root_connected_listening_listen_1(self, parameters):
		socket = parameters[0]
		data = parameters[1]
		self.exit_Root_connected_listening_listen()
		self.received_data += data
		self.raiseInternalEvent(Event("received_data", None, []))
		self.combo_step.setArenaChanged(self.Root_connected_listening)
		self.enter_Root_connected_listening_listen()
	
	def transition_Root_connected_listening_listen_2(self, parameters):
		socket = parameters[0]
		data = parameters[1]
		self.exit_Root_connected_listening_listen()
		self.raiseInternalEvent(Event("received_data", None, []))
		self.combo_step.setArenaChanged(self.Root_connected_listening)
		self.enter_Root_connected_listening_closed()
	
	def generateCandidates_Root_connected_listening_closed(self):
		return False
	
	def generateCandidatesChildren_Root_connected_sending(self):
		if self.current_state[self.Root_connected_sending][0] == self.Root_connected_sending_waiting_for_data:
			return self.generateCandidates_Root_connected_sending_waiting_for_data()
		elif self.current_state[self.Root_connected_sending][0] == self.Root_connected_sending_transferring:
			return self.generateCandidates_Root_connected_sending_transferring()
		return False
	
	def generateCandidates_Root_connected_sending(self):
		if not self.combo_step.isArenaChanged(self.Root_connected_sending):
			return self.generateCandidatesChildren_Root_connected_sending()
		else:
			return True
	
	def generateCandidatesCurrent_Root_connected_sending_waiting_for_data(self):
		enabled_events = self.getEnabledEvents()
		if len(self.send_data) > 0:
			self.small_step.addCandidate(self.transition_Root_connected_sending_waiting_for_data_1, [])
			return True
		return False
	
	def generateCandidates_Root_connected_sending_waiting_for_data(self):
		if not self.combo_step.isArenaChanged(self.Root_connected_sending_waiting_for_data):
			return self.generateCandidatesCurrent_Root_connected_sending_waiting_for_data()
		else:
			return True
	
	def transition_Root_connected_sending_waiting_for_data_1(self, parameters):
		self.exit_Root_connected_sending_waiting_for_data()
		self.big_step.outputEvent(Event("send_socket", "socket_out", [self.socket, self.send_data]))
		self.combo_step.setArenaChanged(self.Root_connected_sending)
		self.enter_Root_connected_sending_transferring()
	
	def generateCandidatesCurrent_Root_connected_sending_transferring(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if (e.name == "sent_socket") and (e.port == "socket_in"):
				parameters = e.parameters
				socket = parameters[0]
				sent_bytes = parameters[1]
				if self.socket == socket:
					self.small_step.addCandidate(self.transition_Root_connected_sending_transferring_1, e.parameters)
					return True
		return False
	
	def generateCandidates_Root_connected_sending_transferring(self):
		if not self.combo_step.isArenaChanged(self.Root_connected_sending_transferring):
			return self.generateCandidatesCurrent_Root_connected_sending_transferring()
		else:
			return True
	
	def transition_Root_connected_sending_transferring_1(self, parameters):
		socket = parameters[0]
		sent_bytes = parameters[1]
		self.exit_Root_connected_sending_transferring()
		self.send_data = self.send_data[sent_bytes:]
		self.combo_step.setArenaChanged(self.Root_connected_sending)
		self.enter_Root_connected_sending_waiting_for_data()
	
	def generateCandidatesChildren_Root_connected_queueing(self):
		if self.current_state[self.Root_connected_queueing][0] == self.Root_connected_queueing_queueing:
			return self.generateCandidates_Root_connected_queueing_queueing()
		return False
	
	def generateCandidates_Root_connected_queueing(self):
		if not self.combo_step.isArenaChanged(self.Root_connected_queueing):
			return self.generateCandidatesChildren_Root_connected_queueing()
		else:
			return True
	
	def generateCandidatesCurrent_Root_connected_queueing_queueing(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "HTTP_input":
				self.small_step.addCandidate(self.transition_Root_connected_queueing_queueing_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_connected_queueing_queueing(self):
		if not self.combo_step.isArenaChanged(self.Root_connected_queueing_queueing):
			return self.generateCandidatesCurrent_Root_connected_queueing_queueing()
		else:
			return True
	
	def transition_Root_connected_queueing_queueing_1(self, parameters):
		data = parameters[0]
		self.exit_Root_connected_queueing_queueing()
		#post_data = "&".join(["%s=%s" % (urllib.quote(k), urllib.quote(v)) for k, v in data.iteritems()])
		post_data = "&".join(["%s=%s" % (k, v) for k, v in data.iteritems()])
		self.send_data += "HTTP/1.0 200 OK\r\n"
		self.send_data += "Content-Length: %s\r\n" % len(post_data)
		self.send_data += "Content-Type: %s; charset=UTF-8\r\n" % "text/plain"
		self.send_data += "\r\n"
		self.send_data += str(post_data)
		self.combo_step.setArenaChanged(self.Root_connected_queueing)
		self.enter_Root_connected_queueing_queueing()
	
	def generateCandidatesChildren_Root_connected_parsing(self):
		if self.current_state[self.Root_connected_parsing][0] == self.Root_connected_parsing_wait_for_header:
			return self.generateCandidates_Root_connected_parsing_wait_for_header()
		elif self.current_state[self.Root_connected_parsing][0] == self.Root_connected_parsing_closing:
			return self.generateCandidates_Root_connected_parsing_closing()
		elif self.current_state[self.Root_connected_parsing][0] == self.Root_connected_parsing_wait_for_payload:
			return self.generateCandidates_Root_connected_parsing_wait_for_payload()
		return False
	
	def generateCandidates_Root_connected_parsing(self):
		if not self.combo_step.isArenaChanged(self.Root_connected_parsing):
			return self.generateCandidatesChildren_Root_connected_parsing()
		else:
			return True
	
	def generateCandidatesCurrent_Root_connected_parsing_wait_for_header(self):
		enabled_events = self.getEnabledEvents()
		if '\r\n\r\n' in self.received_data and self.received_data.startswith('POST'):
			self.small_step.addCandidate(self.transition_Root_connected_parsing_wait_for_header_1, [])
			return True
		enabled_events = self.getEnabledEvents()
		if self.closed and len(self.received_data) == 0:
			self.small_step.addCandidate(self.transition_Root_connected_parsing_wait_for_header_2, [])
			return True
		return False
	
	def generateCandidates_Root_connected_parsing_wait_for_header(self):
		if not self.combo_step.isArenaChanged(self.Root_connected_parsing_wait_for_header):
			return self.generateCandidatesCurrent_Root_connected_parsing_wait_for_header()
		else:
			return True
	
	def transition_Root_connected_parsing_wait_for_header_1(self, parameters):
		self.exit_Root_connected_parsing_wait_for_header()
		header, self.received_data = self.received_data.split("\r\n\r\n", 1)
		header = header.lower()
		if "content-length" in header:
		    _, after = header.split("content-length:", 1)
		    after = after.split("\r\n", 1)[0]
		    after = after.strip()
		    self.length = int(after)
		else:
		    self.length = float('inf')
		self.combo_step.setArenaChanged(self.Root_connected_parsing)
		self.enter_Root_connected_parsing_wait_for_payload()
	
	def transition_Root_connected_parsing_wait_for_header_2(self, parameters):
		self.exit_Root_connected_parsing_wait_for_header()
		self.combo_step.setArenaChanged(self.Root_connected_parsing)
		self.enter_Root_connected_parsing_closing()
	
	def generateCandidatesCurrent_Root_connected_parsing_closing(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "_0after":
				self.small_step.addCandidate(self.transition_Root_connected_parsing_closing_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_connected_parsing_closing(self):
		if not self.combo_step.isArenaChanged(self.Root_connected_parsing_closing):
			return self.generateCandidatesCurrent_Root_connected_parsing_closing()
		else:
			return True
	
	def transition_Root_connected_parsing_closing_1(self, parameters):
		self.exit_Root_connected_parsing_closing()
		self.raiseInternalEvent(Event("close", None, []))
		self.combo_step.setArenaChanged(self.Root_connected_parsing)
		self.enter_Root_connected_parsing_closing()
	
	def generateCandidatesCurrent_Root_connected_parsing_wait_for_payload(self):
		enabled_events = self.getEnabledEvents()
		if len(self.received_data) >= self.length or self.closed:
			self.small_step.addCandidate(self.transition_Root_connected_parsing_wait_for_payload_1, [])
			return True
		return False
	
	def generateCandidates_Root_connected_parsing_wait_for_payload(self):
		if not self.combo_step.isArenaChanged(self.Root_connected_parsing_wait_for_payload):
			return self.generateCandidatesCurrent_Root_connected_parsing_wait_for_payload()
		else:
			return True
	
	def transition_Root_connected_parsing_wait_for_payload_1(self, parameters):
		self.exit_Root_connected_parsing_wait_for_payload()
		if self.length == float('inf'):
		    data = self.received_data
		    self.received_data = ""
		else:
		    data = self.received_data[:self.length]
		    self.received_data = self.received_data[self.length:]
		
		# We support POST data only, so everything is in the data
		try:
		    params = dict([p.split('=') for p in data.split('&')])
		    data = {k: urllib.unquote_plus(v) for k, v in params.iteritems()}
		except:
		    data = {}
		self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("HTTP_output", None, [self.association_name, data])]))
		self.combo_step.setArenaChanged(self.Root_connected_parsing)
		self.enter_Root_connected_parsing_wait_for_header()
	
	def generateCandidates_Root_close(self):
		return False
	
	# Generate transition candidates for current small step
	def generateCandidates(self):
		self.generateCandidates_Root()

class HTTPClient(RuntimeClassBase):
	def __init__(self, controller, hostname, port):
		RuntimeClassBase.__init__(self, controller)
		
		self.semantics.big_step_maximality = StatechartSemantics.TakeMany
		self.semantics.internal_event_lifeline = StatechartSemantics.Queue
		self.semantics.input_event_lifeline = StatechartSemantics.FirstComboStep
		self.semantics.priority = StatechartSemantics.SourceParent
		self.semantics.concurrency = StatechartSemantics.Single
		
		# Call user defined constructor
		HTTPClient.user_defined_constructor(self, hostname, port)
	
	def user_defined_constructor(self, hostname, port):
		self.socket = None
		self.destination = (hostname, port)
		self.received_data = ""
		self.send_data = ""
		self.queue = []
		self.destinations = []
	
	def user_defined_destructor(self):
		pass
	
	def initializeStatechart(self):
		self.current_state[self.Root] = []
		self.current_state[self.Root_connected] = []
		self.current_state[self.Root_connected_listening] = []
		self.current_state[self.Root_connected_sending] = []
		self.current_state[self.Root_connected_queueing] = []
		self.current_state[self.Root_connected_parsing] = []
		
		# Enter default state
		self.enter_Root_init()
	
	# Unique IDs for all statechart nodes
	Root = 0
	Root_connected = 1
	Root_connected_listening = 2
	Root_connected_sending = 3
	Root_connected_queueing = 4
	Root_connected_parsing = 5
	Root_init = 6
	Root_connecting = 7
	Root_connected_listening_listen = 8
	Root_connected_listening_close = 9
	Root_connected_sending_waiting_for_data = 10
	Root_connected_sending_transferring = 11
	Root_connected_queueing_queueing = 12
	Root_connected_parsing_wait_for_header = 13
	Root_connected_parsing_wait_for_payload = 14
	
	# Statechart enter/exit action method(s)
	
	def enter_Root_connected(self):
		self.current_state[self.Root].append(self.Root_connected)
	
	def exit_Root_connected(self):
		self.exit_Root_connected_listening()
		self.exit_Root_connected_sending()
		self.exit_Root_connected_queueing()
		self.exit_Root_connected_parsing()
		self.current_state[self.Root] = []
	
	def enter_Root_connected_listening(self):
		self.current_state[self.Root_connected].append(self.Root_connected_listening)
	
	def exit_Root_connected_listening(self):
		if self.Root_connected_listening_listen in self.current_state[self.Root_connected_listening]:
			self.exit_Root_connected_listening_listen()
		if self.Root_connected_listening_close in self.current_state[self.Root_connected_listening]:
			self.exit_Root_connected_listening_close()
		self.current_state[self.Root_connected] = []
	
	def enter_Root_connected_sending(self):
		self.current_state[self.Root_connected].append(self.Root_connected_sending)
	
	def exit_Root_connected_sending(self):
		if self.Root_connected_sending_waiting_for_data in self.current_state[self.Root_connected_sending]:
			self.exit_Root_connected_sending_waiting_for_data()
		if self.Root_connected_sending_transferring in self.current_state[self.Root_connected_sending]:
			self.exit_Root_connected_sending_transferring()
		self.current_state[self.Root_connected] = []
	
	def enter_Root_connected_queueing(self):
		self.current_state[self.Root_connected].append(self.Root_connected_queueing)
	
	def exit_Root_connected_queueing(self):
		if self.Root_connected_queueing_queueing in self.current_state[self.Root_connected_queueing]:
			self.exit_Root_connected_queueing_queueing()
		self.current_state[self.Root_connected] = []
	
	def enter_Root_connected_parsing(self):
		self.current_state[self.Root_connected].append(self.Root_connected_parsing)
	
	def exit_Root_connected_parsing(self):
		if self.Root_connected_parsing_wait_for_header in self.current_state[self.Root_connected_parsing]:
			self.exit_Root_connected_parsing_wait_for_header()
		if self.Root_connected_parsing_wait_for_payload in self.current_state[self.Root_connected_parsing]:
			self.exit_Root_connected_parsing_wait_for_payload()
		self.current_state[self.Root_connected] = []
	
	def enter_Root_init(self):
		self.big_step.outputEvent(Event("create_socket", "", []))
		self.current_state[self.Root].append(self.Root_init)
	
	def exit_Root_init(self):
		self.current_state[self.Root] = []
	
	def enter_Root_connecting(self):
		self.big_step.outputEvent(Event("connect_socket", "", [self.socket, self.destination]))
		self.current_state[self.Root].append(self.Root_connecting)
	
	def exit_Root_connecting(self):
		self.current_state[self.Root] = []
	
	def enter_Root_connected_listening_listen(self):
		self.big_step.outputEvent(Event("recv_socket", "socket_out", [self.socket]))
		self.current_state[self.Root_connected_listening].append(self.Root_connected_listening_listen)
	
	def exit_Root_connected_listening_listen(self):
		self.current_state[self.Root_connected_listening] = []
	
	def enter_Root_connected_listening_close(self):
		self.current_state[self.Root_connected_listening].append(self.Root_connected_listening_close)
	
	def exit_Root_connected_listening_close(self):
		self.current_state[self.Root_connected_listening] = []
	
	def enter_Root_connected_sending_waiting_for_data(self):
		self.current_state[self.Root_connected_sending].append(self.Root_connected_sending_waiting_for_data)
	
	def exit_Root_connected_sending_waiting_for_data(self):
		self.current_state[self.Root_connected_sending] = []
	
	def enter_Root_connected_sending_transferring(self):
		self.current_state[self.Root_connected_sending].append(self.Root_connected_sending_transferring)
	
	def exit_Root_connected_sending_transferring(self):
		self.current_state[self.Root_connected_sending] = []
	
	def enter_Root_connected_queueing_queueing(self):
		self.current_state[self.Root_connected_queueing].append(self.Root_connected_queueing_queueing)
	
	def exit_Root_connected_queueing_queueing(self):
		self.current_state[self.Root_connected_queueing] = []
	
	def enter_Root_connected_parsing_wait_for_header(self):
		self.current_state[self.Root_connected_parsing].append(self.Root_connected_parsing_wait_for_header)
	
	def exit_Root_connected_parsing_wait_for_header(self):
		self.current_state[self.Root_connected_parsing] = []
	
	def enter_Root_connected_parsing_wait_for_payload(self):
		self.current_state[self.Root_connected_parsing].append(self.Root_connected_parsing_wait_for_payload)
	
	def exit_Root_connected_parsing_wait_for_payload(self):
		self.current_state[self.Root_connected_parsing] = []
	
	# Statechart enter/exit default method(s)
	
	def enterDefault_Root_connected(self):
		self.enter_Root_connected()
		self.enterDefault_Root_connected_listening()
		self.enterDefault_Root_connected_sending()
		self.enterDefault_Root_connected_queueing()
		self.enterDefault_Root_connected_parsing()
	
	def enterDefault_Root_connected_listening(self):
		self.enter_Root_connected_listening()
		self.enter_Root_connected_listening_listen()
	
	def enterDefault_Root_connected_sending(self):
		self.enter_Root_connected_sending()
		self.enter_Root_connected_sending_waiting_for_data()
	
	def enterDefault_Root_connected_queueing(self):
		self.enter_Root_connected_queueing()
		self.enter_Root_connected_queueing_queueing()
	
	def enterDefault_Root_connected_parsing(self):
		self.enter_Root_connected_parsing()
		self.enter_Root_connected_parsing_wait_for_header()
	
	# Statechart transitions
	
	def generateCandidatesChildren_Root(self):
		if self.current_state[self.Root][0] == self.Root_init:
			return self.generateCandidates_Root_init()
		elif self.current_state[self.Root][0] == self.Root_connecting:
			return self.generateCandidates_Root_connecting()
		elif self.current_state[self.Root][0] == self.Root_connected:
			return self.generateCandidates_Root_connected()
		return False
	
	def generateCandidates_Root(self):
		if not self.combo_step.isArenaChanged(self.Root):
			return self.generateCandidatesChildren_Root()
		else:
			return True
	
	def generateCandidatesCurrent_Root_init(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if (e.name == "created_socket") and (e.port == "socket_in"):
				self.small_step.addCandidate(self.transition_Root_init_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_init(self):
		if not self.combo_step.isArenaChanged(self.Root_init):
			return self.generateCandidatesCurrent_Root_init()
		else:
			return True
	
	def transition_Root_init_1(self, parameters):
		socket = parameters[0]
		self.exit_Root_init()
		self.socket = socket
		self.combo_step.setArenaChanged(self.Root)
		self.enter_Root_connecting()
	
	def generateCandidatesCurrent_Root_connecting(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if (e.name == "connected_socket") and (e.port == "socket_in"):
				parameters = e.parameters
				socket = parameters[0]
				if self.socket == socket:
					self.small_step.addCandidate(self.transition_Root_connecting_1, e.parameters)
					return True
		return False
	
	def generateCandidates_Root_connecting(self):
		if not self.combo_step.isArenaChanged(self.Root_connecting):
			return self.generateCandidatesCurrent_Root_connecting()
		else:
			return True
	
	def transition_Root_connecting_1(self, parameters):
		socket = parameters[0]
		self.exit_Root_connecting()
		self.big_step.outputEventOM(Event("broad_cast", None, [Event("http_client_ready", None, [])]))
		self.combo_step.setArenaChanged(self.Root)
		self.enterDefault_Root_connected()
	
	def generateCandidatesChildren_Root_connected(self):
		branch_done = False
		branch_done = (self.generateCandidates_Root_connected_listening() or branch_done)
		branch_done = (self.generateCandidates_Root_connected_sending() or branch_done)
		branch_done = (self.generateCandidates_Root_connected_queueing() or branch_done)
		branch_done = (self.generateCandidates_Root_connected_parsing() or branch_done)
		return branch_done
	
	def generateCandidates_Root_connected(self):
		if not self.combo_step.isArenaChanged(self.Root_connected):
			return self.generateCandidatesChildren_Root_connected()
		else:
			return True
	
	def generateCandidatesChildren_Root_connected_listening(self):
		if self.current_state[self.Root_connected_listening][0] == self.Root_connected_listening_listen:
			return self.generateCandidates_Root_connected_listening_listen()
		elif self.current_state[self.Root_connected_listening][0] == self.Root_connected_listening_close:
			return self.generateCandidates_Root_connected_listening_close()
		return False
	
	def generateCandidates_Root_connected_listening(self):
		if not self.combo_step.isArenaChanged(self.Root_connected_listening):
			return self.generateCandidatesChildren_Root_connected_listening()
		else:
			return True
	
	def generateCandidatesCurrent_Root_connected_listening_listen(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if (e.name == "received_socket") and (e.port == "socket_in"):
				parameters = e.parameters
				socket = parameters[0]
				data = parameters[1]
				if (self.socket == socket) and (len(data) > 0):
					self.small_step.addCandidate(self.transition_Root_connected_listening_listen_1, e.parameters)
					return True
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if (e.name == "received_socket") and (e.port == "socket_in"):
				parameters = e.parameters
				socket = parameters[0]
				data = parameters[1]
				if (self.socket == socket) and (len(data) == 0):
					self.small_step.addCandidate(self.transition_Root_connected_listening_listen_2, e.parameters)
					return True
		return False
	
	def generateCandidates_Root_connected_listening_listen(self):
		if not self.combo_step.isArenaChanged(self.Root_connected_listening_listen):
			return self.generateCandidatesCurrent_Root_connected_listening_listen()
		else:
			return True
	
	def transition_Root_connected_listening_listen_1(self, parameters):
		socket = parameters[0]
		data = parameters[1]
		self.exit_Root_connected_listening_listen()
		self.received_data += data
		self.combo_step.setArenaChanged(self.Root_connected_listening)
		self.enter_Root_connected_listening_listen()
	
	def transition_Root_connected_listening_listen_2(self, parameters):
		socket = parameters[0]
		data = parameters[1]
		self.exit_Root_connected_listening_listen()
		self.combo_step.setArenaChanged(self.Root_connected_listening)
		self.enter_Root_connected_listening_close()
	
	def generateCandidates_Root_connected_listening_close(self):
		return False
	
	def generateCandidatesChildren_Root_connected_sending(self):
		if self.current_state[self.Root_connected_sending][0] == self.Root_connected_sending_waiting_for_data:
			return self.generateCandidates_Root_connected_sending_waiting_for_data()
		elif self.current_state[self.Root_connected_sending][0] == self.Root_connected_sending_transferring:
			return self.generateCandidates_Root_connected_sending_transferring()
		return False
	
	def generateCandidates_Root_connected_sending(self):
		if not self.combo_step.isArenaChanged(self.Root_connected_sending):
			return self.generateCandidatesChildren_Root_connected_sending()
		else:
			return True
	
	def generateCandidatesCurrent_Root_connected_sending_waiting_for_data(self):
		enabled_events = self.getEnabledEvents()
		if len(self.send_data) > 0:
			self.small_step.addCandidate(self.transition_Root_connected_sending_waiting_for_data_1, [])
			return True
		return False
	
	def generateCandidates_Root_connected_sending_waiting_for_data(self):
		if not self.combo_step.isArenaChanged(self.Root_connected_sending_waiting_for_data):
			return self.generateCandidatesCurrent_Root_connected_sending_waiting_for_data()
		else:
			return True
	
	def transition_Root_connected_sending_waiting_for_data_1(self, parameters):
		self.exit_Root_connected_sending_waiting_for_data()
		self.big_step.outputEvent(Event("send_socket", "socket_out", [self.socket, self.send_data]))
		self.combo_step.setArenaChanged(self.Root_connected_sending)
		self.enter_Root_connected_sending_transferring()
	
	def generateCandidatesCurrent_Root_connected_sending_transferring(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if (e.name == "sent_socket") and (e.port == "socket_in"):
				parameters = e.parameters
				socket = parameters[0]
				sent_bytes = parameters[1]
				if self.socket == socket:
					self.small_step.addCandidate(self.transition_Root_connected_sending_transferring_1, e.parameters)
					return True
		return False
	
	def generateCandidates_Root_connected_sending_transferring(self):
		if not self.combo_step.isArenaChanged(self.Root_connected_sending_transferring):
			return self.generateCandidatesCurrent_Root_connected_sending_transferring()
		else:
			return True
	
	def transition_Root_connected_sending_transferring_1(self, parameters):
		socket = parameters[0]
		sent_bytes = parameters[1]
		self.exit_Root_connected_sending_transferring()
		self.send_data = self.send_data[sent_bytes:]
		self.combo_step.setArenaChanged(self.Root_connected_sending)
		self.enter_Root_connected_sending_waiting_for_data()
	
	def generateCandidatesChildren_Root_connected_queueing(self):
		if self.current_state[self.Root_connected_queueing][0] == self.Root_connected_queueing_queueing:
			return self.generateCandidates_Root_connected_queueing_queueing()
		return False
	
	def generateCandidates_Root_connected_queueing(self):
		if not self.combo_step.isArenaChanged(self.Root_connected_queueing):
			return self.generateCandidatesChildren_Root_connected_queueing()
		else:
			return True
	
	def generateCandidatesCurrent_Root_connected_queueing_queueing(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "HTTP_input":
				self.small_step.addCandidate(self.transition_Root_connected_queueing_queueing_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_connected_queueing_queueing(self):
		if not self.combo_step.isArenaChanged(self.Root_connected_queueing_queueing):
			return self.generateCandidatesCurrent_Root_connected_queueing_queueing()
		else:
			return True
	
	def transition_Root_connected_queueing_queueing_1(self, parameters):
		data = parameters[0]
		destination = parameters[1]
		self.exit_Root_connected_queueing_queueing()
		self.send_data += "POST / HTTP/1.0\r\n"
		self.send_data += "Content-Length: %i\r\n" % len(str(data))
		self.send_data += "\r\n"
		self.send_data += data
		self.destinations.append(destination)
		self.combo_step.setArenaChanged(self.Root_connected_queueing)
		self.enter_Root_connected_queueing_queueing()
	
	def generateCandidatesChildren_Root_connected_parsing(self):
		if self.current_state[self.Root_connected_parsing][0] == self.Root_connected_parsing_wait_for_header:
			return self.generateCandidates_Root_connected_parsing_wait_for_header()
		elif self.current_state[self.Root_connected_parsing][0] == self.Root_connected_parsing_wait_for_payload:
			return self.generateCandidates_Root_connected_parsing_wait_for_payload()
		return False
	
	def generateCandidates_Root_connected_parsing(self):
		if not self.combo_step.isArenaChanged(self.Root_connected_parsing):
			return self.generateCandidatesChildren_Root_connected_parsing()
		else:
			return True
	
	def generateCandidatesCurrent_Root_connected_parsing_wait_for_header(self):
		enabled_events = self.getEnabledEvents()
		if '\r\n\r\n' in self.received_data:
			self.small_step.addCandidate(self.transition_Root_connected_parsing_wait_for_header_1, [])
			return True
		return False
	
	def generateCandidates_Root_connected_parsing_wait_for_header(self):
		if not self.combo_step.isArenaChanged(self.Root_connected_parsing_wait_for_header):
			return self.generateCandidatesCurrent_Root_connected_parsing_wait_for_header()
		else:
			return True
	
	def transition_Root_connected_parsing_wait_for_header_1(self, parameters):
		self.exit_Root_connected_parsing_wait_for_header()
		header, self.received_data = self.received_data.split("\r\n\r\n", 1)
		header = header.lower()
		if "content-length" in header:
		    _, after = header.split("content-length:", 1)
		    after, _ = after.split("\r\n", 1)
		    after = after.strip()
		    self.length = int(after)
		else:
		    self.length = float('inf')
		self.combo_step.setArenaChanged(self.Root_connected_parsing)
		self.enter_Root_connected_parsing_wait_for_payload()
	
	def generateCandidatesCurrent_Root_connected_parsing_wait_for_payload(self):
		enabled_events = self.getEnabledEvents()
		if len(self.received_data) >= self.length:
			self.small_step.addCandidate(self.transition_Root_connected_parsing_wait_for_payload_1, [])
			return True
		return False
	
	def generateCandidates_Root_connected_parsing_wait_for_payload(self):
		if not self.combo_step.isArenaChanged(self.Root_connected_parsing_wait_for_payload):
			return self.generateCandidatesCurrent_Root_connected_parsing_wait_for_payload()
		else:
			return True
	
	def transition_Root_connected_parsing_wait_for_payload_1(self, parameters):
		self.exit_Root_connected_parsing_wait_for_payload()
		data = self.received_data[:self.length]
		self.received_data = self.received_data[self.length:]
		params = dict([p.split('=') for p in data.split('&')])
		data = {k: urllib.unquote_plus(v) for k, v in params.iteritems()}
		self.big_step.outputEventOM(Event("narrow_cast", None, [self, self.destinations.pop(0), Event("HTTP_output", None, [data])]))
		self.combo_step.setArenaChanged(self.Root_connected_parsing)
		self.enter_Root_connected_parsing_wait_for_header()
	
	# Generate transition candidates for current small step
	def generateCandidates(self):
		self.generateCandidates_Root()

class LocalMvS(RuntimeClassBase):
	def __init__(self, controller, params):
		RuntimeClassBase.__init__(self, controller)
		
		self.semantics.big_step_maximality = StatechartSemantics.TakeMany
		self.semantics.internal_event_lifeline = StatechartSemantics.Queue
		self.semantics.input_event_lifeline = StatechartSemantics.FirstComboStep
		self.semantics.priority = StatechartSemantics.SourceParent
		self.semantics.concurrency = StatechartSemantics.Single
		
		# Call user defined constructor
		LocalMvS.user_defined_constructor(self, params)
	
	def user_defined_constructor(self, params):
		self.queue = []
		self.destinations = []
		import sys
		sys.path.append("../../state")
		from modelverse_state.main import ModelverseState
		self.mvs = ModelverseState(params[0])
		self.mvs_operations = {
		   "CN": self.mvs.create_node,
		   "CE": self.mvs.create_edge,
		   "CNV": self.mvs.create_nodevalue,
		   "CD": self.mvs.create_dict,
		
		   "RV": self.mvs.read_value,
		   "RO": self.mvs.read_outgoing,
		   "RI": self.mvs.read_incoming,
		   "RE": self.mvs.read_edge,
		   "RD": self.mvs.read_dict,
		   "RDN": self.mvs.read_dict_node,
		   "RDNE": self.mvs.read_dict_node_edge,
		   "RDE": self.mvs.read_dict_edge,
		   "RRD": self.mvs.read_reverse_dict,
		   "RR": self.mvs.read_root,
		   "RDK": self.mvs.read_dict_keys,
		
		   "DE": self.mvs.delete_edge,
		   "DN": self.mvs.delete_node,
		
		   "DUMP": self.mvs.dump_modelverse,
		}
	
	def user_defined_destructor(self):
		pass
	
	
	# User defined method
	def process_message(self, operation_name, parameters):
		op = self.mvs_operations[operation_name]
		return op(*parameters)
	
	def initializeStatechart(self):
		self.current_state[self.Root] = []
		
		# Enter default state
		self.enter_Root_init()
	
	# Unique IDs for all statechart nodes
	Root = 0
	Root_init = 1
	Root_running = 2
	
	# Statechart enter/exit action method(s)
	
	def enter_Root_init(self):
		self.current_state[self.Root].append(self.Root_init)
	
	def exit_Root_init(self):
		self.current_state[self.Root] = []
	
	def enter_Root_running(self):
		self.current_state[self.Root].append(self.Root_running)
	
	def exit_Root_running(self):
		self.current_state[self.Root] = []
	
	# Statechart transitions
	
	def generateCandidatesChildren_Root(self):
		if self.current_state[self.Root][0] == self.Root_init:
			return self.generateCandidates_Root_init()
		elif self.current_state[self.Root][0] == self.Root_running:
			return self.generateCandidates_Root_running()
		return False
	
	def generateCandidates_Root(self):
		if not self.combo_step.isArenaChanged(self.Root):
			return self.generateCandidatesChildren_Root()
		else:
			return True
	
	def generateCandidatesCurrent_Root_init(self):
		enabled_events = self.getEnabledEvents()
		self.small_step.addCandidate(self.transition_Root_init_1, [])
		return True
		return False
	
	def generateCandidates_Root_init(self):
		if not self.combo_step.isArenaChanged(self.Root_init):
			return self.generateCandidatesCurrent_Root_init()
		else:
			return True
	
	def transition_Root_init_1(self, parameters):
		self.exit_Root_init()
		self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("http_client_ready", None, [])]))
		self.combo_step.setArenaChanged(self.Root)
		self.enter_Root_running()
	
	def generateCandidatesCurrent_Root_running(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "HTTP_input":
				self.small_step.addCandidate(self.transition_Root_running_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_running(self):
		if not self.combo_step.isArenaChanged(self.Root_running):
			return self.generateCandidatesCurrent_Root_running()
		else:
			return True
	
	def transition_Root_running_1(self, parameters):
		data = parameters[0]
		destination = parameters[1]
		self.exit_Root_running()
		decoded_data = json.loads(data.split("=",1)[1])
		result = []
		for command, params in decoded_data:
		    result.append(self.process_message(command, params))
		data = {"data": json.dumps(result)}
		self.big_step.outputEventOM(Event("narrow_cast", None, [self, destination, Event("HTTP_output", None, [data])]))
		self.combo_step.setArenaChanged(self.Root)
		self.enter_Root_running()
	
	# Generate transition candidates for current small step
	def generateCandidates(self):
		self.generateCandidates_Root()

class UserStatechart(RuntimeClassBase):
	def __init__(self, controller, username):
		RuntimeClassBase.__init__(self, controller)
		
		self.semantics.big_step_maximality = StatechartSemantics.TakeMany
		self.semantics.internal_event_lifeline = StatechartSemantics.Queue
		self.semantics.input_event_lifeline = StatechartSemantics.FirstComboStep
		self.semantics.priority = StatechartSemantics.SourceParent
		self.semantics.concurrency = StatechartSemantics.Single
		
		# Call user defined constructor
		UserStatechart.user_defined_constructor(self, username)
	
	def user_defined_constructor(self, username):
		self.username = username
		
		self.output_queue = []
		self.source_execution = None
		
		self.request_id = 0
		self.outstanding_execution = None
		self.outstanding_input = {}
		self.outstanding_output = None
	
	def user_defined_destructor(self):
		pass
	
	def initializeStatechart(self):
		self.current_state[self.Root] = []
		self.current_state[self.Root_running] = []
		self.current_state[self.Root_running_execution] = []
		self.current_state[self.Root_running_set_input] = []
		self.current_state[self.Root_running_get_output_queue] = []
		self.current_state[self.Root_running_get_output] = []
		
		# Enter default state
		self.enter_Root_init()
	
	# Unique IDs for all statechart nodes
	Root = 0
	Root_running = 1
	Root_running_execution = 2
	Root_running_set_input = 3
	Root_running_get_output_queue = 4
	Root_running_get_output = 5
	Root_init = 6
	Root_running_execution_init = 7
	Root_running_execution_timeout = 8
	Root_running_set_input_fetch = 9
	Root_running_get_output_queue_waiting = 10
	Root_running_get_output_try_execute = 11
	Root_running_get_output_waiting = 12
	
	# Statechart enter/exit action method(s)
	
	def enter_Root_running(self):
		self.current_state[self.Root].append(self.Root_running)
	
	def exit_Root_running(self):
		self.exit_Root_running_execution()
		self.exit_Root_running_set_input()
		self.exit_Root_running_get_output_queue()
		self.exit_Root_running_get_output()
		self.current_state[self.Root] = []
	
	def enter_Root_running_execution(self):
		self.current_state[self.Root_running].append(self.Root_running_execution)
	
	def exit_Root_running_execution(self):
		if self.Root_running_execution_init in self.current_state[self.Root_running_execution]:
			self.exit_Root_running_execution_init()
		if self.Root_running_execution_timeout in self.current_state[self.Root_running_execution]:
			self.exit_Root_running_execution_timeout()
		self.current_state[self.Root_running] = []
	
	def enter_Root_running_set_input(self):
		self.current_state[self.Root_running].append(self.Root_running_set_input)
	
	def exit_Root_running_set_input(self):
		if self.Root_running_set_input_fetch in self.current_state[self.Root_running_set_input]:
			self.exit_Root_running_set_input_fetch()
		self.current_state[self.Root_running] = []
	
	def enter_Root_running_get_output_queue(self):
		self.current_state[self.Root_running].append(self.Root_running_get_output_queue)
	
	def exit_Root_running_get_output_queue(self):
		if self.Root_running_get_output_queue_waiting in self.current_state[self.Root_running_get_output_queue]:
			self.exit_Root_running_get_output_queue_waiting()
		self.current_state[self.Root_running] = []
	
	def enter_Root_running_get_output(self):
		self.current_state[self.Root_running].append(self.Root_running_get_output)
	
	def exit_Root_running_get_output(self):
		if self.Root_running_get_output_try_execute in self.current_state[self.Root_running_get_output]:
			self.exit_Root_running_get_output_try_execute()
		if self.Root_running_get_output_waiting in self.current_state[self.Root_running_get_output]:
			self.exit_Root_running_get_output_waiting()
		self.current_state[self.Root_running] = []
	
	def enter_Root_init(self):
		self.current_state[self.Root].append(self.Root_init)
	
	def exit_Root_init(self):
		self.current_state[self.Root] = []
	
	def enter_Root_running_execution_init(self):
		self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent/executor', Event("execute", None, [self.returnpath, self.username, 'execute_rule', [], self.request_id])]))
		self.outstanding_execution = self.request_id
		self.request_id += 1
		self.current_state[self.Root_running_execution].append(self.Root_running_execution_init)
	
	def exit_Root_running_execution_init(self):
		self.current_state[self.Root_running_execution] = []
	
	def enter_Root_running_execution_timeout(self):
		self.timers[0] = 1.0
		self.current_state[self.Root_running_execution].append(self.Root_running_execution_timeout)
	
	def exit_Root_running_execution_timeout(self):
		self.timers.pop(0, None)
		self.current_state[self.Root_running_execution] = []
	
	def enter_Root_running_set_input_fetch(self):
		self.current_state[self.Root_running_set_input].append(self.Root_running_set_input_fetch)
	
	def exit_Root_running_set_input_fetch(self):
		self.current_state[self.Root_running_set_input] = []
	
	def enter_Root_running_get_output_queue_waiting(self):
		self.current_state[self.Root_running_get_output_queue].append(self.Root_running_get_output_queue_waiting)
	
	def exit_Root_running_get_output_queue_waiting(self):
		self.current_state[self.Root_running_get_output_queue] = []
	
	def enter_Root_running_get_output_try_execute(self):
		self.current_state[self.Root_running_get_output].append(self.Root_running_get_output_try_execute)
	
	def exit_Root_running_get_output_try_execute(self):
		self.current_state[self.Root_running_get_output] = []
	
	def enter_Root_running_get_output_waiting(self):
		self.timers[1] = 1.0
		self.current_state[self.Root_running_get_output].append(self.Root_running_get_output_waiting)
	
	def exit_Root_running_get_output_waiting(self):
		self.timers.pop(1, None)
		self.current_state[self.Root_running_get_output] = []
	
	# Statechart enter/exit default method(s)
	
	def enterDefault_Root_running(self):
		self.enter_Root_running()
		self.enterDefault_Root_running_execution()
		self.enterDefault_Root_running_set_input()
		self.enterDefault_Root_running_get_output_queue()
		self.enterDefault_Root_running_get_output()
	
	def enterDefault_Root_running_execution(self):
		self.enter_Root_running_execution()
		self.enter_Root_running_execution_init()
	
	def enterDefault_Root_running_set_input(self):
		self.enter_Root_running_set_input()
		self.enter_Root_running_set_input_fetch()
	
	def enterDefault_Root_running_get_output_queue(self):
		self.enter_Root_running_get_output_queue()
		self.enter_Root_running_get_output_queue_waiting()
	
	def enterDefault_Root_running_get_output(self):
		self.enter_Root_running_get_output()
		self.enter_Root_running_get_output_try_execute()
	
	# Statechart transitions
	
	def generateCandidatesChildren_Root(self):
		if self.current_state[self.Root][0] == self.Root_init:
			return self.generateCandidates_Root_init()
		elif self.current_state[self.Root][0] == self.Root_running:
			return self.generateCandidates_Root_running()
		return False
	
	def generateCandidates_Root(self):
		if not self.combo_step.isArenaChanged(self.Root):
			return self.generateCandidatesChildren_Root()
		else:
			return True
	
	def generateCandidatesCurrent_Root_init(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "set_returnpath":
				self.small_step.addCandidate(self.transition_Root_init_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_init(self):
		if not self.combo_step.isArenaChanged(self.Root_init):
			return self.generateCandidatesCurrent_Root_init()
		else:
			return True
	
	def transition_Root_init_1(self, parameters):
		returnpath = parameters[0]
		self.exit_Root_init()
		self.returnpath = returnpath
		self.combo_step.setArenaChanged(self.Root)
		self.enterDefault_Root_running()
	
	def generateCandidatesChildren_Root_running(self):
		branch_done = False
		branch_done = (self.generateCandidates_Root_running_execution() or branch_done)
		branch_done = (self.generateCandidates_Root_running_set_input() or branch_done)
		branch_done = (self.generateCandidates_Root_running_get_output_queue() or branch_done)
		branch_done = (self.generateCandidates_Root_running_get_output() or branch_done)
		return branch_done
	
	def generateCandidates_Root_running(self):
		if not self.combo_step.isArenaChanged(self.Root_running):
			return self.generateCandidatesChildren_Root_running()
		else:
			return True
	
	def generateCandidatesChildren_Root_running_execution(self):
		if self.current_state[self.Root_running_execution][0] == self.Root_running_execution_init:
			return self.generateCandidates_Root_running_execution_init()
		elif self.current_state[self.Root_running_execution][0] == self.Root_running_execution_timeout:
			return self.generateCandidates_Root_running_execution_timeout()
		return False
	
	def generateCandidates_Root_running_execution(self):
		if not self.combo_step.isArenaChanged(self.Root_running_execution):
			return self.generateCandidatesChildren_Root_running_execution()
		else:
			return True
	
	def generateCandidatesCurrent_Root_running_execution_init(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "executed":
				parameters = e.parameters
				returnvalue = parameters[0]
				success = parameters[1]
				request_id = parameters[2]
				if success and self.outstanding_execution == request_id:
					self.small_step.addCandidate(self.transition_Root_running_execution_init_1, e.parameters)
					return True
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "executed":
				parameters = e.parameters
				returnvalue = parameters[0]
				success = parameters[1]
				request_id = parameters[2]
				if not success and self.outstanding_execution == request_id:
					self.small_step.addCandidate(self.transition_Root_running_execution_init_2, e.parameters)
					return True
		return False
	
	def generateCandidates_Root_running_execution_init(self):
		if not self.combo_step.isArenaChanged(self.Root_running_execution_init):
			return self.generateCandidatesCurrent_Root_running_execution_init()
		else:
			return True
	
	def transition_Root_running_execution_init_1(self, parameters):
		returnvalue = parameters[0]
		success = parameters[1]
		request_id = parameters[2]
		self.exit_Root_running_execution_init()
		self.combo_step.setArenaChanged(self.Root_running_execution)
		self.enter_Root_running_execution_init()
	
	def transition_Root_running_execution_init_2(self, parameters):
		returnvalue = parameters[0]
		success = parameters[1]
		request_id = parameters[2]
		self.exit_Root_running_execution_init()
		self.combo_step.setArenaChanged(self.Root_running_execution)
		self.enter_Root_running_execution_timeout()
	
	def generateCandidatesCurrent_Root_running_execution_timeout(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "_0after":
				self.small_step.addCandidate(self.transition_Root_running_execution_timeout_1, e.parameters)
				return True
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "set_input_done":
				self.small_step.addCandidate(self.transition_Root_running_execution_timeout_2, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_running_execution_timeout(self):
		if not self.combo_step.isArenaChanged(self.Root_running_execution_timeout):
			return self.generateCandidatesCurrent_Root_running_execution_timeout()
		else:
			return True
	
	def transition_Root_running_execution_timeout_1(self, parameters):
		self.exit_Root_running_execution_timeout()
		self.combo_step.setArenaChanged(self.Root_running_execution)
		self.enter_Root_running_execution_init()
	
	def transition_Root_running_execution_timeout_2(self, parameters):
		self.exit_Root_running_execution_timeout()
		self.combo_step.setArenaChanged(self.Root_running_execution)
		self.enter_Root_running_execution_init()
	
	def generateCandidatesChildren_Root_running_set_input(self):
		if self.current_state[self.Root_running_set_input][0] == self.Root_running_set_input_fetch:
			return self.generateCandidates_Root_running_set_input_fetch()
		return False
	
	def generateCandidates_Root_running_set_input(self):
		if not self.combo_step.isArenaChanged(self.Root_running_set_input):
			return self.generateCandidatesChildren_Root_running_set_input()
		else:
			return True
	
	def generateCandidatesCurrent_Root_running_set_input_fetch(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "set_input":
				self.small_step.addCandidate(self.transition_Root_running_set_input_fetch_1, e.parameters)
				return True
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "executed":
				parameters = e.parameters
				returnvalue = parameters[0]
				success = parameters[1]
				request_id = parameters[2]
				if request_id in self.outstanding_input:
					self.small_step.addCandidate(self.transition_Root_running_set_input_fetch_2, e.parameters)
					return True
		return False
	
	def generateCandidates_Root_running_set_input_fetch(self):
		if not self.combo_step.isArenaChanged(self.Root_running_set_input_fetch):
			return self.generateCandidatesCurrent_Root_running_set_input_fetch()
		else:
			return True
	
	def transition_Root_running_set_input_fetch_1(self, parameters):
		source = parameters[0]
		args = parameters[1]
		self.exit_Root_running_set_input_fetch()
		self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent/executor', Event("execute", None, [self.returnpath, self.username, 'set_input', args, self.request_id])]))
		self.outstanding_input[self.request_id] = source
		self.request_id += 1
		self.combo_step.setArenaChanged(self.Root_running_set_input)
		self.enter_Root_running_set_input_fetch()
	
	def transition_Root_running_set_input_fetch_2(self, parameters):
		returnvalue = parameters[0]
		success = parameters[1]
		request_id = parameters[2]
		self.exit_Root_running_set_input_fetch()
		source = self.outstanding_input.pop(request_id)
		self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent/to_mvi/' + source, Event("HTTP_input", None, [returnvalue])]))
		self.raiseInternalEvent(Event("set_input_done", None, []))
		self.combo_step.setArenaChanged(self.Root_running_set_input)
		self.enter_Root_running_set_input_fetch()
	
	def generateCandidatesChildren_Root_running_get_output_queue(self):
		if self.current_state[self.Root_running_get_output_queue][0] == self.Root_running_get_output_queue_waiting:
			return self.generateCandidates_Root_running_get_output_queue_waiting()
		return False
	
	def generateCandidates_Root_running_get_output_queue(self):
		if not self.combo_step.isArenaChanged(self.Root_running_get_output_queue):
			return self.generateCandidatesChildren_Root_running_get_output_queue()
		else:
			return True
	
	def generateCandidatesCurrent_Root_running_get_output_queue_waiting(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "get_output":
				self.small_step.addCandidate(self.transition_Root_running_get_output_queue_waiting_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_running_get_output_queue_waiting(self):
		if not self.combo_step.isArenaChanged(self.Root_running_get_output_queue_waiting):
			return self.generateCandidatesCurrent_Root_running_get_output_queue_waiting()
		else:
			return True
	
	def transition_Root_running_get_output_queue_waiting_1(self, parameters):
		source = parameters[0]
		args = parameters[1]
		self.exit_Root_running_get_output_queue_waiting()
		self.output_queue.append(source)
		self.combo_step.setArenaChanged(self.Root_running_get_output_queue)
		self.enter_Root_running_get_output_queue_waiting()
	
	def generateCandidatesChildren_Root_running_get_output(self):
		if self.current_state[self.Root_running_get_output][0] == self.Root_running_get_output_try_execute:
			return self.generateCandidates_Root_running_get_output_try_execute()
		elif self.current_state[self.Root_running_get_output][0] == self.Root_running_get_output_waiting:
			return self.generateCandidates_Root_running_get_output_waiting()
		return False
	
	def generateCandidates_Root_running_get_output(self):
		if not self.combo_step.isArenaChanged(self.Root_running_get_output):
			return self.generateCandidatesChildren_Root_running_get_output()
		else:
			return True
	
	def generateCandidatesCurrent_Root_running_get_output_try_execute(self):
		enabled_events = self.getEnabledEvents()
		if self.outstanding_output is None and self.output_queue:
			self.small_step.addCandidate(self.transition_Root_running_get_output_try_execute_1, [])
			return True
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "executed":
				parameters = e.parameters
				returnvalue = parameters[0]
				success = parameters[1]
				request_id = parameters[2]
				if success and request_id == self.outstanding_output:
					self.small_step.addCandidate(self.transition_Root_running_get_output_try_execute_2, e.parameters)
					return True
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "executed":
				parameters = e.parameters
				returnvalue = parameters[0]
				success = parameters[1]
				request_id = parameters[2]
				if not success and request_id == self.outstanding_output:
					self.small_step.addCandidate(self.transition_Root_running_get_output_try_execute_3, e.parameters)
					return True
		return False
	
	def generateCandidates_Root_running_get_output_try_execute(self):
		if not self.combo_step.isArenaChanged(self.Root_running_get_output_try_execute):
			return self.generateCandidatesCurrent_Root_running_get_output_try_execute()
		else:
			return True
	
	def transition_Root_running_get_output_try_execute_1(self, parameters):
		self.exit_Root_running_get_output_try_execute()
		self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent/executor', Event("execute", None, [self.returnpath, self.username, 'get_output', [], self.request_id])]))
		self.outstanding_output = self.request_id
		self.request_id += 1
		self.combo_step.setArenaChanged(self.Root_running_get_output)
		self.enter_Root_running_get_output_try_execute()
	
	def transition_Root_running_get_output_try_execute_2(self, parameters):
		returnvalue = parameters[0]
		success = parameters[1]
		request_id = parameters[2]
		self.exit_Root_running_get_output_try_execute()
		self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent/to_mvi/' + self.output_queue.pop(0), Event("HTTP_input", None, [returnvalue])]))
		self.outstanding_output = None
		self.combo_step.setArenaChanged(self.Root_running_get_output)
		self.enter_Root_running_get_output_try_execute()
	
	def transition_Root_running_get_output_try_execute_3(self, parameters):
		returnvalue = parameters[0]
		success = parameters[1]
		request_id = parameters[2]
		self.exit_Root_running_get_output_try_execute()
		self.outstanding_output = None
		self.combo_step.setArenaChanged(self.Root_running_get_output)
		self.enter_Root_running_get_output_waiting()
	
	def generateCandidatesCurrent_Root_running_get_output_waiting(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "_1after":
				self.small_step.addCandidate(self.transition_Root_running_get_output_waiting_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_running_get_output_waiting(self):
		if not self.combo_step.isArenaChanged(self.Root_running_get_output_waiting):
			return self.generateCandidatesCurrent_Root_running_get_output_waiting()
		else:
			return True
	
	def transition_Root_running_get_output_waiting_1(self, parameters):
		self.exit_Root_running_get_output_waiting()
		self.combo_step.setArenaChanged(self.Root_running_get_output)
		self.enter_Root_running_get_output_try_execute()
	
	# Generate transition candidates for current small step
	def generateCandidates(self):
		self.generateCandidates_Root()

class Executor(RuntimeClassBase):
	def __init__(self, controller, mvk):
		RuntimeClassBase.__init__(self, controller)
		
		self.semantics.big_step_maximality = StatechartSemantics.TakeMany
		self.semantics.internal_event_lifeline = StatechartSemantics.Queue
		self.semantics.input_event_lifeline = StatechartSemantics.FirstComboStep
		self.semantics.priority = StatechartSemantics.SourceParent
		self.semantics.concurrency = StatechartSemantics.Single
		
		# Call user defined constructor
		Executor.user_defined_constructor(self, mvk)
	
	def user_defined_constructor(self, mvk):
		self.request_queue = [("", "", "load_primitives", [], None)]
		self.mvk = mvk
		self.first = True
		self.mvs_response = None
	
	def user_defined_destructor(self):
		pass
	
	def initializeStatechart(self):
		self.current_state[self.Root] = []
		self.current_state[self.Root_init] = []
		self.current_state[self.Root_init_queue] = []
		self.current_state[self.Root_init_execute] = []
		
		# Enter default state
		self.enterDefault_Root_init()
	
	# Unique IDs for all statechart nodes
	Root = 0
	Root_init = 1
	Root_init_queue = 2
	Root_init_execute = 3
	Root_init_queue_queue = 4
	Root_init_execute_idle = 5
	Root_init_execute_execution = 6
	Root_init_execute_waiting_for_response = 7
	
	# Statechart enter/exit action method(s)
	
	def enter_Root_init(self):
		self.current_state[self.Root].append(self.Root_init)
	
	def exit_Root_init(self):
		self.exit_Root_init_queue()
		self.exit_Root_init_execute()
		self.current_state[self.Root] = []
	
	def enter_Root_init_queue(self):
		self.current_state[self.Root_init].append(self.Root_init_queue)
	
	def exit_Root_init_queue(self):
		if self.Root_init_queue_queue in self.current_state[self.Root_init_queue]:
			self.exit_Root_init_queue_queue()
		self.current_state[self.Root_init] = []
	
	def enter_Root_init_execute(self):
		self.current_state[self.Root_init].append(self.Root_init_execute)
	
	def exit_Root_init_execute(self):
		if self.Root_init_execute_idle in self.current_state[self.Root_init_execute]:
			self.exit_Root_init_execute_idle()
		if self.Root_init_execute_execution in self.current_state[self.Root_init_execute]:
			self.exit_Root_init_execute_execution()
		if self.Root_init_execute_waiting_for_response in self.current_state[self.Root_init_execute]:
			self.exit_Root_init_execute_waiting_for_response()
		self.current_state[self.Root_init] = []
	
	def enter_Root_init_queue_queue(self):
		self.current_state[self.Root_init_queue].append(self.Root_init_queue_queue)
	
	def exit_Root_init_queue_queue(self):
		self.current_state[self.Root_init_queue] = []
	
	def enter_Root_init_execute_idle(self):
		self.current_state[self.Root_init_execute].append(self.Root_init_execute_idle)
	
	def exit_Root_init_execute_idle(self):
		self.current_state[self.Root_init_execute] = []
	
	def enter_Root_init_execute_execution(self):
		try:
		    _, username, operation, params, _ = self.request_queue[0]
		    self.mvs_commands = self.mvk.execute_yields(username, operation, params, self.mvs_response)
		except:
		    import traceback
		    traceback.print_exc()
		    print("Exec error")
		    #TODO for debugging
		    sys.exit(0)
		
		    self.mvs_commands = None
		self.current_state[self.Root_init_execute].append(self.Root_init_execute_execution)
	
	def exit_Root_init_execute_execution(self):
		self.current_state[self.Root_init_execute] = []
	
	def enter_Root_init_execute_waiting_for_response(self):
		self.current_state[self.Root_init_execute].append(self.Root_init_execute_waiting_for_response)
	
	def exit_Root_init_execute_waiting_for_response(self):
		self.current_state[self.Root_init_execute] = []
	
	# Statechart enter/exit default method(s)
	
	def enterDefault_Root_init(self):
		self.enter_Root_init()
		self.enterDefault_Root_init_queue()
		self.enterDefault_Root_init_execute()
	
	def enterDefault_Root_init_queue(self):
		self.enter_Root_init_queue()
		self.enter_Root_init_queue_queue()
	
	def enterDefault_Root_init_execute(self):
		self.enter_Root_init_execute()
		self.enter_Root_init_execute_idle()
	
	# Statechart transitions
	
	def generateCandidatesChildren_Root(self):
		if self.current_state[self.Root][0] == self.Root_init:
			return self.generateCandidates_Root_init()
		return False
	
	def generateCandidates_Root(self):
		if not self.combo_step.isArenaChanged(self.Root):
			return self.generateCandidatesChildren_Root()
		else:
			return True
	
	def generateCandidatesChildren_Root_init(self):
		branch_done = False
		branch_done = (self.generateCandidates_Root_init_queue() or branch_done)
		branch_done = (self.generateCandidates_Root_init_execute() or branch_done)
		return branch_done
	
	def generateCandidates_Root_init(self):
		if not self.combo_step.isArenaChanged(self.Root_init):
			return self.generateCandidatesChildren_Root_init()
		else:
			return True
	
	def generateCandidatesChildren_Root_init_queue(self):
		if self.current_state[self.Root_init_queue][0] == self.Root_init_queue_queue:
			return self.generateCandidates_Root_init_queue_queue()
		return False
	
	def generateCandidates_Root_init_queue(self):
		if not self.combo_step.isArenaChanged(self.Root_init_queue):
			return self.generateCandidatesChildren_Root_init_queue()
		else:
			return True
	
	def generateCandidatesCurrent_Root_init_queue_queue(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "execute":
				self.small_step.addCandidate(self.transition_Root_init_queue_queue_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_init_queue_queue(self):
		if not self.combo_step.isArenaChanged(self.Root_init_queue_queue):
			return self.generateCandidatesCurrent_Root_init_queue_queue()
		else:
			return True
	
	def transition_Root_init_queue_queue_1(self, parameters):
		returnpath = parameters[0]
		username = parameters[1]
		operation = parameters[2]
		params = parameters[3]
		request_id = parameters[4]
		self.exit_Root_init_queue_queue()
		self.request_queue.append(("/" + returnpath, username, operation, params, request_id))
		self.combo_step.setArenaChanged(self.Root_init_queue)
		self.enter_Root_init_queue_queue()
	
	def generateCandidatesChildren_Root_init_execute(self):
		if self.current_state[self.Root_init_execute][0] == self.Root_init_execute_idle:
			return self.generateCandidates_Root_init_execute_idle()
		elif self.current_state[self.Root_init_execute][0] == self.Root_init_execute_execution:
			return self.generateCandidates_Root_init_execute_execution()
		elif self.current_state[self.Root_init_execute][0] == self.Root_init_execute_waiting_for_response:
			return self.generateCandidates_Root_init_execute_waiting_for_response()
		return False
	
	def generateCandidates_Root_init_execute(self):
		if not self.combo_step.isArenaChanged(self.Root_init_execute):
			return self.generateCandidatesChildren_Root_init_execute()
		else:
			return True
	
	def generateCandidatesCurrent_Root_init_execute_idle(self):
		enabled_events = self.getEnabledEvents()
		if self.request_queue:
			self.small_step.addCandidate(self.transition_Root_init_execute_idle_1, [])
			return True
		return False
	
	def generateCandidates_Root_init_execute_idle(self):
		if not self.combo_step.isArenaChanged(self.Root_init_execute_idle):
			return self.generateCandidatesCurrent_Root_init_execute_idle()
		else:
			return True
	
	def transition_Root_init_execute_idle_1(self, parameters):
		self.exit_Root_init_execute_idle()
		self.combo_step.setArenaChanged(self.Root_init_execute)
		self.enter_Root_init_execute_execution()
	
	def generateCandidatesCurrent_Root_init_execute_execution(self):
		enabled_events = self.getEnabledEvents()
		if self.mvs_commands is None:
			self.small_step.addCandidate(self.transition_Root_init_execute_execution_1, [])
			return True
		enabled_events = self.getEnabledEvents()
		if len(self.mvs_commands) > 0:
			self.small_step.addCandidate(self.transition_Root_init_execute_execution_2, [])
			return True
		enabled_events = self.getEnabledEvents()
		if len(self.mvs_commands) == 0:
			self.small_step.addCandidate(self.transition_Root_init_execute_execution_3, [])
			return True
		return False
	
	def generateCandidates_Root_init_execute_execution(self):
		if not self.combo_step.isArenaChanged(self.Root_init_execute_execution):
			return self.generateCandidatesCurrent_Root_init_execute_execution()
		else:
			return True
	
	def transition_Root_init_execute_execution_1(self, parameters):
		self.exit_Root_init_execute_execution()
		returnpath, _, _, _, request_id = self.request_queue.pop(0)
		self.mvs_response = None
		self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent' + returnpath, Event("executed", None, [self.mvk.returnvalue, self.mvk.success, request_id])]))
		self.mvk.returnvalue = None
		self.mvk.success = True
		self.first = True
		self.combo_step.setArenaChanged(self.Root_init_execute)
		self.enter_Root_init_execute_idle()
	
	def transition_Root_init_execute_execution_2(self, parameters):
		self.exit_Root_init_execute_execution()
		self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent/to_mvs', Event("HTTP_input", None, ['requests=%s' % json.dumps(self.mvs_commands), 'parent/executor'])]))
		self.combo_step.setArenaChanged(self.Root_init_execute)
		self.enter_Root_init_execute_waiting_for_response()
	
	def transition_Root_init_execute_execution_3(self, parameters):
		self.exit_Root_init_execute_execution()
		self.combo_step.setArenaChanged(self.Root_init_execute)
		self.enter_Root_init_execute_execution()
	
	def generateCandidatesCurrent_Root_init_execute_waiting_for_response(self):
		enabled_events = self.getEnabledEvents()
		for e in enabled_events:
			if e.name == "HTTP_output":
				self.small_step.addCandidate(self.transition_Root_init_execute_waiting_for_response_1, e.parameters)
				return True
		return False
	
	def generateCandidates_Root_init_execute_waiting_for_response(self):
		if not self.combo_step.isArenaChanged(self.Root_init_execute_waiting_for_response):
			return self.generateCandidatesCurrent_Root_init_execute_waiting_for_response()
		else:
			return True
	
	def transition_Root_init_execute_waiting_for_response_1(self, parameters):
		data = parameters[0]
		self.exit_Root_init_execute_waiting_for_response()
		self.mvs_response = [v[0] for v in json.loads(data["data"])]
		if len(self.mvs_response) == 1:
		    self.mvs_response = self.mvs_response[0]
		self.combo_step.setArenaChanged(self.Root_init_execute)
		self.enter_Root_init_execute_execution()
	
	# Generate transition candidates for current small step
	def generateCandidates(self):
		self.generateCandidates_Root()

class ObjectManager(ObjectManagerBase):
	def __init__(self, controller):
		ObjectManagerBase.__init__(self, controller)
	
	def instantiate(self, class_name, construct_params):
		if class_name == "MvKController":
			instance = MvKController(self.controller, construct_params[0])
			instance.associations = {}
			instance.associations["to_mvs"] = Association("HTTPClient", 1, 1)
			instance.associations["to_mvi"] = Association("Server", 1, 1)
			instance.associations["users"] = Association("UserStatechart", 0, -1)
			instance.associations["executor"] = Association("Executor", 1, 1)
		elif class_name == "Server":
			instance = Server(self.controller, construct_params[0], construct_params[1])
			instance.associations = {}
			instance.associations["sockets"] = Association("Socket", 0, -1)
			instance.associations["parent"] = Association("MvKController", 1, 1)
		elif class_name == "Socket":
			instance = Socket(self.controller, construct_params[0])
			instance.associations = {}
			instance.associations["parent"] = Association("Server", 1, 1)
		elif class_name == "HTTPClient":
			instance = HTTPClient(self.controller, construct_params[0], construct_params[1])
			instance.associations = {}
			instance.associations["parent"] = Association("MvKController", 1, 1)
		elif class_name == "LocalMvS":
			instance = LocalMvS(self.controller, construct_params[0])
			instance.associations = {}
			instance.associations["parent"] = Association("MvKController", 1, 1)
		elif class_name == "UserStatechart":
			instance = UserStatechart(self.controller, construct_params[0])
			instance.associations = {}
			instance.associations["parent"] = Association("MvKController", 1, 1)
		elif class_name == "Executor":
			instance = Executor(self.controller, construct_params[0])
			instance.associations = {}
			instance.associations["parent"] = Association("MvKController", 1, 1)
		return instance

class Controller(ThreadsControllerBase):
	def __init__(self, params, keep_running = None):
		if keep_running == None: keep_running = True
		ThreadsControllerBase.__init__(self, ObjectManager(self), keep_running)
		self.addInputPort("socket_in")
		self.addOutputPort("socket_out")
		self.object_manager.createInstance("MvKController", [params])