/**
   * Returns non-null Cloud application module mapped to the first module in the list of modules. If
   * the cloud module module does not exist for the given module, it will attempt to create it. To
   * avoid re-creating a cloud application module that may have been deleted, restrict invoking this
   * method to only operations that start, restart, or update an application. Should not be called
   * when deleting an application.
   *
   * @param local WST modules representing app to be deployed.
   * @return non-null Cloud Application module mapped to the given WST module.
   * @throws CoreException if no modules specified or mapped cloud application module cannot be
   *     resolved.
   */
  protected CloudFoundryApplicationModule getOrCreateCloudApplicationModule(IModule[] modules)
      throws CoreException {

    IModule module = modules[0];

    CloudFoundryServer cloudServer = getBehaviour().getCloudFoundryServer();

    CloudFoundryApplicationModule appModule = cloudServer.getCloudModule(module);

    if (appModule == null) {
      throw CloudErrorUtil.toCoreException(
          NLS.bind(INTERNAL_ERROR_NO_MAPPED_CLOUD_MODULE, modules[0].getId()));
    }

    return appModule;
  }
  @Override
  public void run(IProgressMonitor monitor) throws CoreException {

    try {
      doApplicationOperation(monitor);
      getBehaviour().getRefreshHandler().scheduleRefreshForDeploymentChange(getModule());
    } catch (OperationCanceledException e) {
      // ignore so webtools does not show an exception
      ((Server) getBehaviour().getServer()).setModuleState(getModules(), IServer.STATE_UNKNOWN);

      // If application operations, like Restart, Start, or
      // PushApplication are canceled, then the publish state is
      // 'indeterminate'
      // TODO: Don't reference internal Server class. We need to revisit
      // this change and revert back to the original state.
      ((Server) getBehaviour().getServer())
          .setServerPublishState(IServer.PUBLISH_STATE_INCREMENTAL);
      ((Server) getBehaviour().getServer())
          .setModulePublishState(modules, IServer.PUBLISH_STATE_INCREMENTAL);

      // Record the canceled operation 'description' to the log file.
      CloudFoundryPlugin.logWarning(e.getMessage());

      CloudFoundryServer cloudServer = getBehaviour().getCloudFoundryServer();

      CloudFoundryApplicationModule appModule = cloudServer.getCloudModule(getModule());
      if (appModule != null && e.getMessage() != null) {
        CloudFoundryPlugin.getCallback()
            .printToConsole(
                cloudServer,
                appModule,
                NLS.bind(
                        Messages.AbstractPublishApplicationOperation_OPERATION_CANCELED,
                        e.getMessage())
                    + '\n',
                false,
                false);
      }
    }
  }