<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def update_workspace(self, workspace_id, name=None, description=None, language=None, metadata=None, learning_opt_out=None, system_settings=None, intents=None, entities=None, dialog_nodes=None, counterexamples=None, append=None, **kwargs):
 """ Update workspace. Update an existing workspace with new or modified data. You must provide component objects defining the content of the updated workspace. This operation is limited to 30 request per 30 minutes. For more information, see **Rate limiting**. :param str workspace_id: Unique identifier of the workspace. :param str name: The name of the workspace. This string cannot contain carriage return, newline, or tab characters, and it must be no longer than 64 characters. :param str description: The description of the workspace. This string cannot contain carriage return, newline, or tab characters, and it must be no longer than 128 characters. :param str language: The language of the workspace. :param dict metadata: Any metadata related to the workspace. :param bool learning_opt_out: Whether training data from the workspace (including artifacts such as intents and entities) can be used by IBM for general service improvements. `true` indicates that workspace training data is not to be used. :param WorkspaceSystemSettings system_settings: Global settings for the workspace. :param list[CreateIntent] intents: An array of objects defining the intents for the workspace. :param list[CreateEntity] entities: An array of objects describing the entities for the workspace. :param list[DialogNode] dialog_nodes: An array of objects describing the dialog nodes in the workspace. :param list[Counterexample] counterexamples: An array of objects defining input examples that have been marked as irrelevant input. :param bool append: Whether the new data is to be appended to the existing data in the workspace. If **append**=`false`, elements included in the new data completely replace the corresponding existing elements, including all subelements. For example, if the new data includes **entities** and **append**=`false`, all existing entities in the workspace are discarded and replaced with the new entities. If **append**=`true`, existing elements are preserved, and the new elements are added. If any elements in the new data collide with existing elements, the update request fails. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. :rtype: DetailedResponse """


        if workspace_id is None:
            raise ValueError('workspace_id must be provided')
        if system_settings is not None:
            system_settings = self._convert_model(system_settings,
                                                  WorkspaceSystemSettings)
        if intents is not None:
            intents = [self._convert_model(x, CreateIntent) for x in intents]
        if entities is not None:
            entities = [self._convert_model(x, CreateEntity) for x in entities]
        if dialog_nodes is not None:
            dialog_nodes = [
                self._convert_model(x, DialogNode) for x in dialog_nodes
            ]
        if counterexamples is not None:
            counterexamples = [
                self._convert_model(x, Counterexample) for x in counterexamples
            ]

        headers = {}
        if 'headers' in kwargs:
            headers.update(kwargs.get('headers'))
        sdk_headers = get_sdk_headers('conversation', 'V1', 'update_workspace')
        headers.update(sdk_headers)

        params = {'version': self.version, 'append': append}

        data = {
            'name': name,
            'description': description,
            'language': language,
            'metadata': metadata,
            'learning_opt_out': learning_opt_out,
            'system_settings': system_settings,
            'intents': intents,
            'entities': entities,
            'dialog_nodes': dialog_nodes,
            'counterexamples': counterexamples
        }

        url = '/v1/workspaces/{0}'.format(*self._encode_path_vars(workspace_id))
        response = self.request(
            method='POST',
            url=url,
            headers=headers,
            params=params,
            json=data,
            accept_json=True)
        return response