public void doTool(
      HttpServletRequest req,
      HttpServletResponse res,
      Session session,
      String placementId,
      String toolContextPath,
      String toolPathInfo)
      throws ToolException, IOException {

    if (portal.redirectIfLoggedOut(res)) return;

    // find the tool from some site
    ToolConfiguration siteTool = SiteService.findTool(placementId);
    if (siteTool == null) {
      portal.doError(req, res, session, Portal.ERROR_WORKSITE);
      return;
    }

    // Reset the tool state if requested
    if (portalService.isResetRequested(req)) {
      Session s = SessionManager.getCurrentSession();
      ToolSession ts = s.getToolSession(placementId);
      ts.clearAttributes();
      portalService.setResetState(null);
      M_log.debug("Tool state reset");
    }

    // find the tool registered for this

    ActiveTool tool = ActiveToolManager.getActiveTool(siteTool.getToolId());
    if (tool == null) {
      portal.doError(req, res, session, Portal.ERROR_WORKSITE);
      return;
    }

    // permission check - visit the site (unless the tool is configured to
    // bypass)
    Site site = null;
    if (tool.getAccessSecurity() == Tool.AccessSecurity.PORTAL) {
      try {
        site = SiteService.getSiteVisit(siteTool.getSiteId());
      } catch (IdUnusedException e) {
        portal.doError(req, res, session, Portal.ERROR_WORKSITE);
        return;
      } catch (PermissionException e) {
        // if not logged in, give them a chance
        if (session.getUserId() == null) {
          portal.doLogin(req, res, session, URLUtils.getSafePathInfo(req), false);
        } else {
          portal.doError(req, res, session, Portal.ERROR_WORKSITE);
        }
        return;
      }
    }

    // Check to see if the tool is visible
    if (!ToolManager.isVisible(site, siteTool)) {
      portal.doError(req, res, session, Portal.ERROR_WORKSITE);
      return;
    }

    if (portal.isPortletPlacement(siteTool)) {

      String siteType = portal.calcSiteType(siteTool.getSiteId());

      // form a context sensitive title
      String title =
          ServerConfigurationService.getString("ui.service", "Sakai")
              + " : "
              + portal.getSiteHelper().getUserSpecificSiteTitle(site, false)
              + " : "
              + siteTool.getTitle();

      PortalRenderContext rcontext =
          portal.startPageContext(siteType, title, siteTool.getSkin(), req);

      Map m = portal.includeTool(res, req, siteTool);
      rcontext.put("tool", m);

      portal.sendResponse(rcontext, res, "tool", null);

    } else {
      M_log.debug("forwardtool in ToolHandler");
      portal.forwardTool(
          tool, req, res, siteTool, siteTool.getSkin(), toolContextPath, toolPathInfo);
    }
  }
  private String addOrCreateTool(Map payload, boolean trustedConsumer, User user, Site site)
      throws LTIException {
    // Check if the site already has the tool
    String toolPlacementId = null;
    String tool_id = (String) payload.get("tool_id");
    try {
      site = SiteService.getSite(site.getId());
      ToolConfiguration toolConfig = site.getToolForCommonId(tool_id);
      if (toolConfig != null) {
        toolPlacementId = toolConfig.getId();
      }
    } catch (Exception e) {
      M_log.warn(e.getLocalizedMessage(), e);
      throw new LTIException("launch.tool.search", "tool_id=" + tool_id, e);
    }

    if (M_log.isDebugEnabled()) {
      M_log.debug("toolPlacementId=" + toolPlacementId);
    }

    // If tool not in site, and we are a trusted consumer, error
    // Otherwise, add tool to the site
    ToolConfiguration toolConfig = null;
    if (BasicLTIUtil.isBlank(toolPlacementId)) {
      try {
        SitePage sitePageEdit = null;
        sitePageEdit = site.addPage();
        sitePageEdit.setTitle(tool_id);

        toolConfig = sitePageEdit.addTool();
        toolConfig.setTool(tool_id, ToolManager.getTool(tool_id));
        toolConfig.setTitle(tool_id);

        Properties propsedit = toolConfig.getPlacementConfig();
        propsedit.setProperty(
            BASICLTI_RESOURCE_LINK, (String) payload.get(BasicLTIConstants.RESOURCE_LINK_ID));
        pushAdvisor();
        try {
          SiteService.save(site);
          M_log.info("Tool added, tool_id=" + tool_id + ", siteId=" + site.getId());
        } catch (Exception e) {
          throw new LTIException(
              "launch.site.save", "tool_id=" + tool_id + ", siteId=" + site.getId(), e);
        } finally {
          popAdvisor();
        }
        toolPlacementId = toolConfig.getId();

      } catch (Exception e) {
        throw new LTIException(
            "launch.tool.add", "tool_id=" + tool_id + ", siteId=" + site.getId(), e);
      }
    }

    // Get ToolConfiguration for tool if not already setup
    if (toolConfig == null) {
      toolConfig = site.getToolForCommonId(tool_id);
    }

    // Check user has access to this tool in this site
    if (!ToolManager.isVisible(site, toolConfig)) {
      M_log.warn(
          "Not allowed to access tool user_id="
              + user.getId()
              + " site="
              + site.getId()
              + " tool="
              + tool_id);
      throw new LTIException(
          "launch.site.tool.denied",
          "user_id=" + user.getId() + " site=" + site.getId() + " tool=" + tool_id,
          null);
    }
    return toolPlacementId;
  }