<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def set_variable(self, key, value, per_reference=False, access_key=None, data_type=None):
 """Sets a global variable :param key: the key of the global variable to be set :param value: the new value of the global variable :param per_reference: a flag to decide if the variable should be stored per reference or per value :param access_key: if the variable was explicitly locked with the rafcon.state lock_variable :raises exceptions.RuntimeError: if a wrong access key is passed """

        key = str(key)  # Ensure that we have the same string type for all keys (under Python2 and 3!)
        if self.variable_exist(key):
            if data_type is None:
                data_type = self.__global_variable_type_dictionary[key]
        else:
            if data_type is None:
                data_type = type(None)
        assert isinstance(data_type, type)
        self.check_value_and_type(value, data_type)

        with self.__global_lock:
            unlock = True
            if self.variable_exist(key):
                if self.is_locked(key) and self.__access_keys[key] != access_key:
                    raise RuntimeError("Wrong access key for accessing global variable")
                elif self.is_locked(key):
                    unlock = False
                else:
                    access_key = self.lock_variable(key, block=True)
            else:
                self.__variable_locks[key] = Lock()
                access_key = self.lock_variable(key, block=True)

            # --- variable locked
            if per_reference:
                self.__global_variable_dictionary[key] = value
                self.__global_variable_type_dictionary[key] = data_type
                self.__variable_references[key] = True
            else:
                self.__global_variable_dictionary[key] = copy.deepcopy(value)
                self.__global_variable_type_dictionary[key] = data_type
                self.__variable_references[key] = False
            # --- release variable

            if unlock:
                self.unlock_variable(key, access_key)

        logger.debug("Global variable '{}' was set to value '{}' with type '{}'".format(key, value, data_type.__name__))