function Replica.ListenToChange(S,Z,H)if type(H)~="\102\117\110\099\116\105\111\110"then error("\091\082\101\112\108\105\099\097\067\111\110\116\114\111\108\108\101\114\093\058 \079\110\108\121 \097 \102\117\110\099\116\105\111\110 \099\097\110 \098\101 \115\101\116 \097\115 \108\105\115\116\101\110\101\114 \105\110 \082\101\112\108\105\099\097\058\076\105\115\116\101\110\084\111\067\104\097\110\103\101\040\041")end local w=type(Z)=="\115\116\114\105\110\103"and StringPathToArray(Z)or Z if#w<1 then error("\091\082\101\112\108\105\099\097\067\111\110\116\114\111\108\108\101\114\093\058 \080\097\115\115\101\100 \101\109\112\116\121 \112\097\116\104 - \097 \118\097\108\117\101 \107\101\121 \109\117\115\116 \098\101 \115\112\101\099\105\102\105\101\100")end local e=CreateTableListenerPathIndex(S,w,2)table.insert(e,H)return Madwork.NewArrayScriptConnection(e,H,CleanTableListenerTable,{S._table_listeners;w})end function Replica.ListenToNewKey(S,Z,H)if type(H)~="\102\117\110\099\116\105\111\110"then error("\091\082\101\112\108\105\099\097\067\111\110\116\114\111\108\108\101\114\093\058 \079\110\108\121 \097 \102\117\110\099\116\105\111\110 \099\097\110 \098\101 \115\101\116 \097\115 \108\105\115\116\101\110\101\114 \105\110 \082\101\112\108\105\099\097\058\076\105\115\116\101\110\084\111\078\101\119\075\101\121\040\041")end local w=type(Z)=="\115\116\114\105\110\103"and StringPathToArray(Z)or Z local e=CreateTableListenerPathIndex(S,w,3)table.insert(e,H)if#w==0 then return Madwork.NewArrayScriptConnection(e,H)else return Madwork.NewArrayScriptConnection(e,H,CleanTableListenerTable,{S._table_listeners,w})end end function Replica.ListenToArrayInsert(S,Z,H)if type(H)~="\102\117\110\099\116\105\111\110"then error("\091\082\101\112\108\105\099\097\067\111\110\116\114\111\108\108\101\114\093\058 \079\110\108\121 \097 \102\117\110\099\116\105\111\110 \099\097\110 \098\101 \115\101\116 \097\115 \108\105\115\116\101\110\101\114 \105\110 \082\101\112\108\105\099\097\058\076\105\115\116\101\110\084\111\065\114\114\097\121\073\110\115\101\114\116\040\041")end local w=type(Z)=="\115\116\114\105\110\103"and StringPathToArray(Z)or Z local e=CreateTableListenerPathIndex(S,w,4)table.insert(e,H)if#w==0 then return Madwork.NewArrayScriptConnection(e,H)else return Madwork.NewArrayScriptConnection(e,H,CleanTableListenerTable,{S._table_listeners;w})end end function Replica.ListenToArraySet(S,Z,H)if type(H)~="\102\117\110\099\116\105\111\110"then error("\091\082\101\112\108\105\099\097\067\111\110\116\114\111\108\108\101\114\093\058 \079\110\108\121 \097 \102\117\110\099\116\105\111\110 \099\097\110 \098\101 \115\101\116 \097\115 \108\105\115\116\101\110\101\114 \105\110 \082\101\112\108\105\099\097\058\076\105\115\116\101\110\084\111\065\114\114\097\121\083\101\116\040\041")end local w=type(Z)=="\115\116\114\105\110\103"and StringPathToArray(Z)or Z local e=CreateTableListenerPathIndex(S,w,5)table.insert(e,H)if#w==0 then return Madwork.NewArrayScriptConnection(e,H)else return Madwork.NewArrayScriptConnection(e,H,CleanTableListenerTable,{S._table_listeners,w})end end function Replica.ListenToArrayRemove(S,Z,H)if type(H)~="\102\117\110\099\116\105\111\110"then error("\091\082\101\112\108\105\099\097\067\111\110\116\114\111\108\108\101\114\093\058 \079\110\108\121 \097 \102\117\110\099\116\105\111\110 \099\097\110 \098\101 \115\101\116 \097\115 \108\105\115\116\101\110\101\114 \105\110 \082\101\112\108\105\099\097\058\076\105\115\116\101\110\084\111\065\114\114\097\121\082\101\109\111\118\101\040\041")end local w=type(Z)=="\115\116\114\105\110\103"and StringPathToArray(Z)or Z local e=CreateTableListenerPathIndex(S,w,6)table.insert(e,H)if#w==0 then return Madwork.NewArrayScriptConnection(e,H)else return Madwork.NewArrayScriptConnection(e,H,CleanTableListenerTable,{S._table_listeners,w})end end function Replica.ListenToWrite(S,Z,H)if type(H)~="\102\117\110\099\116\105\111\110"then error("\091\082\101\112\108\105\099\097\067\111\110\116\114\111\108\108\101\114\093\058 \079\110\108\121 \097 \102\117\110\099\116\105\111\110 \099\097\110 \098\101 \115\101\116 \097\115 \108\105\115\116\101\110\101\114 \105\110 \082\101\112\108\105\099\097\058\076\105\115\116\101\110\084\111\087\114\105\116\101\040\041")end if S._write_lib==nil then error("\091\082\101\112\108\105\099\097\067\111\110\116\114\111\108\108\101\114\093\058 \095\119\114\105\116\101\095\108\105\098 \119\097\115 \110\111\116 \100\101\099\108\097\114\101\100 \102\111\114 \116\104\105\115 \114\101\112\108\105\099\097")end local w=S._write_lib_dictionary[Z]if w==nil then error("\091\082\101\112\108\105\099\097\067\111\110\116\114\111\108\108\101\114\093\058 \087\114\105\116\101 \102\117\110\099\116\105\111\110 \""..(Z.."\" \110\111\116 \100\101\099\108\097\114\101\100 \105\110\115\105\100\101 \095\119\114\105\116\101\095\108\105\098 \111\102 \116\104\105\115 \114\101\112\108\105\099\097"))end local e=S._function_listeners[w]if e==nil then e={}S._function_listeners[w]=e end table.insert(e,H)return Madwork.NewArrayScriptConnection(e,H)end function Replica.ListenToRaw(H,Z)local S=H._raw_listeners table.insert(S,Z)return Madwork.NewArrayScriptConnection(S,Z)end
-- Listening:
function Replica:ListenToChange(path, listener) --> [ScriptConnection] listener(new_value)
	if type(listener) ~= "function" then
		error("[ReplicaController]: Only a function can be set as listener in Replica:ListenToChange()")
	end

	local path_array = (type(path) == "string") and StringPathToArray(path) or path
	if #path_array < 1 then
		error("[ReplicaController]: Passed empty path - a value key must be specified")
	end
	-- Getting listener table for given path:
	local listeners = CreateTableListenerPathIndex(self, path_array, 2)
	table.insert(listeners, listener)
	-- ScriptConnection which allows the disconnection of the listener:
	return Madwork.NewArrayScriptConnection(
		listeners,
		listener,
		CleanTableListenerTable,
		{ self._table_listeners, path_array }
	)
end

function Replica:ListenToNewKey(path, listener) --> [ScriptConnection] listener(new_value, new_key)
	if type(listener) ~= "function" then
		error("[ReplicaController]: Only a function can be set as listener in Replica:ListenToNewKey()")
	end

	local path_array = (type(path) == "string") and StringPathToArray(path) or path
	-- Getting listener table for given path:
	local listeners = CreateTableListenerPathIndex(self, path_array, 3)
	table.insert(listeners, listener)
	-- ScriptConnection which allows the disconnection of the listener:
	if #path_array == 0 then
		return Madwork.NewArrayScriptConnection(listeners, listener)
	else
		return Madwork.NewArrayScriptConnection(
			listeners,
			listener,
			CleanTableListenerTable,
			{ self._table_listeners, path_array }
		)
	end
end

function Replica:ListenToArrayInsert(path, listener) --> [ScriptConnection] listener(new_value, new_index)
	if type(listener) ~= "function" then
		error("[ReplicaController]: Only a function can be set as listener in Replica:ListenToArrayInsert()")
	end

	local path_array = (type(path) == "string") and StringPathToArray(path) or path
	-- Getting listener table for given path:
	local listeners = CreateTableListenerPathIndex(self, path_array, 4)
	table.insert(listeners, listener)
	-- ScriptConnection which allows the disconnection of the listener:
	if #path_array == 0 then
		return Madwork.NewArrayScriptConnection(listeners, listener)
	else
		return Madwork.NewArrayScriptConnection(
			listeners,
			listener,
			CleanTableListenerTable,
			{ self._table_listeners, path_array }
		)
	end
end

function Replica:ListenToArraySet(path, listener) --> [ScriptConnection] listener(new_value, index)
	if type(listener) ~= "function" then
		error("[ReplicaController]: Only a function can be set as listener in Replica:ListenToArraySet()")
	end

	local path_array = (type(path) == "string") and StringPathToArray(path) or path
	-- Getting listener table for given path:
	local listeners = CreateTableListenerPathIndex(self, path_array, 5)
	table.insert(listeners, listener)
	-- ScriptConnection which allows the disconnection of the listener:
	if #path_array == 0 then
		return Madwork.NewArrayScriptConnection(listeners, listener)
	else
		return Madwork.NewArrayScriptConnection(
			listeners,
			listener,
			CleanTableListenerTable,
			{ self._table_listeners, path_array }
		)
	end
end

function Replica:ListenToArrayRemove(path, listener) --> [ScriptConnection] listener(old_value, old_index)
	if type(listener) ~= "function" then
		error("[ReplicaController]: Only a function can be set as listener in Replica:ListenToArrayRemove()")
	end

	local path_array = (type(path) == "string") and StringPathToArray(path) or path
	-- Getting listener table for given path:
	local listeners = CreateTableListenerPathIndex(self, path_array, 6)
	table.insert(listeners, listener)
	-- ScriptConnection which allows the disconnection of the listener:
	if #path_array == 0 then
		return Madwork.NewArrayScriptConnection(listeners, listener)
	else
		return Madwork.NewArrayScriptConnection(
			listeners,
			listener,
			CleanTableListenerTable,
			{ self._table_listeners, path_array }
		)
	end
end

function Replica:ListenToWrite(function_name, listener) --> [ScriptConnection] listener(params...)
	if type(listener) ~= "function" then
		error("[ReplicaController]: Only a function can be set as listener in Replica:ListenToWrite()")
	end
	if self._write_lib == nil then
		error("[ReplicaController]: _write_lib was not declared for this replica")
	end

	local func_id = self._write_lib_dictionary[function_name]
	if func_id == nil then
		error(
			'[ReplicaController]: Write function "'
				.. function_name
				.. '" not declared inside _write_lib of this replica'
		)
	end

	-- Getting listener table for given path:
	local listeners = self._function_listeners[func_id]
	if listeners == nil then
		listeners = {}
		self._function_listeners[func_id] = listeners
	end
	table.insert(listeners, listener)
	-- ScriptConnection which allows the disconnection of the listener:
	return Madwork.NewArrayScriptConnection(listeners, listener)
end

function Replica:ListenToRaw(listener) --> [ScriptConnection] (action_name, params...)
	local listeners = self._raw_listeners
	table.insert(listeners, listener)
	return Madwork.NewArrayScriptConnection(listeners, listener)
end
