docs: @RequestMapping(method = RequestMethod.POST, params = "action=addPortlet")
      public ModelAndView addPortlet(HttpServletRequest request, HttpServletResponse response)
              throws IOException, PortalException {
  
          IUserInstance ui = userInstanceManager.getUserInstance(request);
          UserPreferencesManager upm = (UserPreferencesManager) ui.getPreferencesManager();
          IUserLayoutManager ulm = upm.getUserLayoutManager();
          final Locale locale = RequestContextUtils.getLocale(request);
  
          // gather the parameters we need to move a channel
          String destinationId = request.getParameter("elementID");
          String sourceId = request.getParameter("channelID");
          String method = request.getParameter("position");
          String fname = request.getParameter("fname");
  
          if (destinationId == null) {
              String tabName = request.getParameter("tabName");
              if (tabName != null) {
                  destinationId = getTabIdFromName(ulm.getUserLayout(), tabName);
              }
          }
  
          IPortletDefinition definition;
          if (sourceId != null) definition = portletDefinitionRegistry.getPortletDefinition(sourceId);
          else if (fname != null)
              definition = portletDefinitionRegistry.getPortletDefinitionByFname(fname);
          else {
              logger.error("SourceId or fname invalid when adding a portlet");
              response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
              return new ModelAndView(
                      "jsonView", Collections.singletonMap("error", "SourceId or fname invalid"));
          }
  
          IUserLayoutChannelDescription channel = new UserLayoutChannelDescription(definition);
  
          IUserLayoutNodeDescription node;
          if (isTab(ulm, destinationId)) {
              node = addNodeToTab(ulm, channel, destinationId);
  
          } else {
              boolean isInsert = method != null && method.equals("insertBefore");
  
              // If neither an insert or type folder - Can't "insert into" non-folder
              if (!(isInsert || isFolder(ulm, destinationId))) {
                  logger.error("Cannot insert into portlet element");
                  response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                  return new ModelAndView(
                          "jsonView",
                          Collections.singletonMap("error", "Cannot insert into portlet element"));
              }
  
              String siblingId = isInsert ? destinationId : null;
              String target = isInsert ? ulm.getParentId(destinationId) : destinationId;
  
              // move the channel into the column
              node = ulm.addNode(channel, target, siblingId);
          }
  
          if (node == null) {
              response.setStatus(HttpServletResponse.SC_FORBIDDEN);
              return new ModelAndView(
                      "jsonView",
                      Collections.singletonMap(
                              "error",
                              getMessage("error.add.element", "Unable to add element", locale)));
          }
  
          String nodeId = node.getId();
  
          try {
              // save the user's layout
              ulm.saveUserLayout();
              if (addedWindowState != null) {
                  IPortletWindow portletWindow =
                          this.portletWindowRegistry.getOrCreateDefaultPortletWindowByFname(
                                  request, channel.getFunctionalName());
                  portletWindow.setWindowState(addedWindowState);
                  this.portletWindowRegistry.storePortletWindow(request, portletWindow);
              }
          } catch (PortalException e) {
              return handlePersistError(request, response, e);
          }
  
          Map<String, String> model = new HashMap<>();
          model.put("response", getMessage("success.add.portlet", "Added a new channel", locale));
          model.put("newNodeId", nodeId);
          return new ModelAndView("jsonView", model);
      }