<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def save_app(self, si, logger, vcenter_data_model, reservation_id, save_app_actions, cancellation_context):
 """ Cretaes an artifact of an app, that can later be restored :param vcenter_data_model: VMwarevCenterResourceModel :param vim.ServiceInstance si: py_vmomi service instance :type si: vim.ServiceInstance :param logger: Logger :type logger: cloudshell.core.logger.qs_logger.get_qs_logger :param list[SaveApp] save_app_actions: :param cancellation_context: """

        results = []

        logger.info('Save Sandbox command starting on ' + vcenter_data_model.default_datacenter)

        if not save_app_actions:
            raise Exception('Failed to save app, missing data in request.')

        actions_grouped_by_save_types = groupby(save_app_actions, lambda x: x.actionParams.saveDeploymentModel)
        # artifactSaver or artifactHandler are different ways to save artifacts. For example, currently
        # we clone a vm, thenk take a snapshot. restore will be to deploy from linked snapshot
        # a future artifact handler we might develop is save vm to OVF file and restore from file.
        artifactSaversToActions = {ArtifactHandler.factory(k,
                                                           self.pyvmomi_service,
                                                           vcenter_data_model,
                                                           si,
                                                           logger,
                                                           self.deployer,
                                                           reservation_id,
                                                           self.resource_model_parser,
                                                           self.snapshot_saver,
                                                           self.task_waiter,
                                                           self.folder_manager,
                                                           self.port_group_configurer,
                                                           self.cs)
                                   : list(g)
                                   for k, g in actions_grouped_by_save_types}

        self.validate_requested_save_types_supported(artifactSaversToActions,
                                                     logger,
                                                     results)

        error_results = [r for r in results if not r.success]
        if not error_results:
            logger.info('Handling Save App requests')
            results = self._execute_save_actions_using_pool(artifactSaversToActions,
                                                            cancellation_context,
                                                            logger,
                                                            results)
            logger.info('Completed Save Sandbox command')
        else:
            logger.error('Some save app requests were not valid, Save Sandbox command failed.')
        return results