Save the complete customization to the activity.

        :param widgets: The complete set of widgets to be customized

def _save_customization(self, widgets):
        """
        Save the complete customization to the activity.

        :param widgets: The complete set of widgets to be customized
        """
        if len(widgets) > 0:
            # Get the current customization and only replace the 'ext' part of it
            customization = self.activity._json_data.get('customization', dict())
            if customization:
                customization['ext'] = dict(widgets=widgets)
            else:
                customization = dict(ext=dict(widgets=widgets))

        # Empty the customization if if the widgets list is empty
        else:
            customization = None

        # perform validation
        if customization:
            validate(customization, widgetconfig_json_schema)

        # Save to the activity and store the saved activity to self
        response = self._client._request("PUT",
                                         self._client._build_url("activity", activity_id=str(self.activity.id)),
                                         json=dict(customization=customization))
        if response.status_code != requests.codes.ok:  # pragma: no cover
            raise APIError("Could not save customization ({})".format(response))
        else:
            # refresh the activity json
            self.activity = self._client.activity(pk=self.activity.id)