/**
   * Remove an application from a workspace application list.
   *
   * @param appName the application to remove from the list
   * @param spaceName the name of the workspace to remove the application from
   * @param withData delete all data belonging to the application (located in its wiki space) if
   *     true, only hides the application from the list otherwise.
   */
  public void removeApplicationFromSpace(
      String appName, String spaceName, boolean withData, XWikiContext context)
      throws WorkspacesManagerException {
    try {
      XWikiApplication app = getXWikiApplicationManagerApi(context).getApplicationDocument(appName);

      if (app == null)
        throw new WorkspacesManagerException(
            WorkspacesManagerException.MODULE_PLUGIN_XWS,
            WorkspacesManagerException.ERROR_XWSMGR_APPNOTFOUND_ON_INSTALL,
            "Could not find application descriptor when trying to install application ["
                + appName
                + "]"
                + "in space ["
                + spaceName
                + "]");

      String appSpace = spaceName + XWIKI_WORKSPACE_APPSEPARATOR + app.getAppName();

      if (!withData) {
        // not implemented yet.
        throw new WorkspacesManagerException();
      } else {
        ApplicationManagerExtension ext = getApplicationManagerExtension(app, context);
        // execute, if needed pre uninstall operations
        if (ext != null) {
          ext.preUninstall(appSpace, context);
        }
        // remove all documents that belong to the wiki space in which lives the application
        for (XWikiDocument doc :
            context
                .getWiki()
                .getStore()
                .searchDocuments("where doc.web = '" + appSpace + "'", context)) {
          context.getWiki().deleteAllDocuments(doc, false, context);
        }
        // execute, if needed post uninstall operations
        if (ext != null) {
          ext.postUninstall(appSpace, context);
        }
      }
    } catch (XWikiException e) {
      throw new WorkspacesManagerException(e);
    }
  }
  /**
   * Install an application in the given space, by copying or linking documents. Read the list of
   * documents to include (link) and copy from the {@link ApplicationManagerPlugin} and save their
   * content locally in a wiki space (web) composed of the space wiki name and the application name.
   * Also make the application web inherits its rights from the space root space (web).
   *
   * @param appName the name of the application to install
   * @param spaceName the wiki name of the space to install the application in
   * @throws SpaceManagerException
   */
  public void installApplicationInSpace(String appName, String spaceName, XWikiContext context)
      throws WorkspacesManagerException {
    // TODO Note that this method makes a deviant usage of the application
    // manager plugin and XWiki application objects.
    // It uses the application field docsToInclude and documents
    // to make a local installation (as opposed as cross-wiki global
    // installation, which the application manager is initially designed
    // for).
    // In the future, the application manager should be able to
    // handle local installation/local copy parameters, and the
    // SpaceManagerPlugin implements a method to install a space
    // from an application or application list.

    // get the application manager api

    try {
      // Retrieve the application descriptor
      XWikiApplication app = getXWikiApplicationManagerApi(context).getApplicationDocument(appName);

      if (app == null)
        throw new WorkspacesManagerException(
            WorkspacesManagerException.MODULE_PLUGIN_XWS,
            WorkspacesManagerException.ERROR_XWSMGR_APPNOTFOUND_ON_INSTALL,
            "Could not find application descriptor when trying to install application ["
                + appName
                + "]"
                + "in space ["
                + spaceName
                + "]");

      ApplicationManagerExtension ext = getApplicationManagerExtension(app, context);

      String appSpace = spaceName + XWIKI_WORKSPACE_APPSEPARATOR + app.getAppName();

      // execute, if needed pre install operations
      if (ext != null) {
        ext.preInstall(appSpace, context);
      }

      // Retrieve the application document list
      Set<String> appDocs = app.getDocumentsNames(false, false);

      // Retrieve the application documents to include
      Set<String> docsToInclude = app.getDocsNameToInclude(true);

      for (String docFullName : appDocs) {
        // If the doc is not in the include list,
        // We copy it to the target space
        if (!docsToInclude.contains(docFullName)) {
          String docName = docFullName.substring(docFullName.indexOf('.') + 1);
          String targetDocName = appSpace + XWIKI_SPACE_SEPARATOR + docName;
          context.getWiki().copyDocument(docFullName, targetDocName, true, context);
        }
      }

      for (String docFullName : docsToInclude) {

        String docName = docFullName.substring(docFullName.indexOf('.') + 1);

        // Compute the target doc name based on application name, space
        // name and document
        // name
        // EX: Space_Wiki.WebHome for "Space" space name, "Wiki" appname
        // and "WebHome" doc
        String targetDocName = appSpace + XWIKI_SPACE_SEPARATOR + docName;
        XWikiDocument targetDoc = context.getWiki().getDocument(targetDocName, context);

        // Link the content with the application code
        targetDoc.setContent(
            MessageFormat.format(
                "#includeInContext(\"{0}\")", new java.lang.Object[] {docFullName}));

        // Save the document
        context.getWiki().saveDocument(targetDoc, context);
      }

      if (appDocs.size() > 0) {
        // if we've installed anything,
        // make the installed app inherit its right from the Workspace
        // root web
        XWikiDocument appPreferences =
            context
                .getWiki()
                .getDocument(appSpace + XWIKI_SPACE_SEPARATOR + "WebPreferences", context);
        BaseObject pObj = appPreferences.getObject("XWiki.XWikiPreferences", true, context);
        pObj.setStringValue("parent", spaceName);
        context.getWiki().saveDocument(appPreferences, context);
      }

      // execute, if needed post install operations
      if (ext != null) {
        ext.postInstall(appSpace, context);
      }

    } catch (XWikiException e) {
      throw new WorkspacesManagerException(e);
    }
  }