<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_properties(self, properties):
 """ Updates the service properties :param properties: The new properties :raise TypeError: The argument is not a dictionary """

        if not isinstance(properties, dict):
            raise TypeError("Waiting for dictionary")

        # Keys that must not be updated
        for forbidden_key in OBJECTCLASS, SERVICE_ID:
            try:
                del properties[forbidden_key]
            except KeyError:
                pass

        to_delete = []
        for key, value in properties.items():
            if self.__properties.get(key) == value:
                # No update
                to_delete.append(key)

        for key in to_delete:
            # Remove unchanged properties
            del properties[key]

        if not properties:
            # Nothing to do
            return

        # Ensure that the service has a valid service ranking
        try:
            properties[SERVICE_RANKING] = int(properties[SERVICE_RANKING])
        except (ValueError, TypeError):
            # Bad value: ignore update
            del properties[SERVICE_RANKING]
        except KeyError:
            # Service ranking not updated: ignore
            pass

        # pylint: disable=W0212
        with self.__reference._props_lock:
            # Update the properties
            previous = self.__properties.copy()
            self.__properties.update(properties)

            if self.__reference.needs_sort_update():
                # The sort key and the registry must be updated
                self.__update_callback(self.__reference)

            # Trigger a new computation in the framework
            event = ServiceEvent(
                ServiceEvent.MODIFIED, self.__reference, previous
            )

            self.__framework._dispatcher.fire_service_event(event)