@Test
  public void testPreferencesWithModeEditGuestInPublicLayoutWithPermission() throws Exception {

    _layout.setPrivateLayout(false);

    PowerMockito.mockStatic(PortletLocalServiceUtil.class);

    Mockito.when(PortletLocalServiceUtil.getPortletById(_layout.getCompanyId(), _PORTLET_ID))
        .thenReturn(getGroupPortlet());

    PowerMockito.mockStatic(LayoutPermissionUtil.class);

    Mockito.when(
            LayoutPermissionUtil.contains(
                Mockito.any(PermissionChecker.class),
                Mockito.eq(_layout),
                Mockito.eq(ActionKeys.UPDATE)))
        .thenReturn(true);

    long siteGroupId = _layout.getGroupId();
    boolean modeEditGuest = true;

    PortletPreferencesFactoryUtil.getPortletPreferencesIds(
        siteGroupId, _USER_ID, _layout, _PORTLET_ID, modeEditGuest);
  }
  @Override
  public boolean isShow() {
    try {
      Layout layout = getLayout();

      if (layout == null) {
        return false;
      }

      Group group = layout.getGroup();

      if (group.isLayoutPrototype()) {
        return false;
      }

      if (LayoutPermissionUtil.contains(
          themeDisplay.getPermissionChecker(), getLayout(), ActionKeys.PERMISSIONS)) {

        return true;
      }
    } catch (Exception e) {
    }

    return false;
  }
  @Override
  public void removePortletId(long userId, String portletId, boolean cleanUp) {

    try {
      Portlet portlet = PortletLocalServiceUtil.getPortletById(getCompanyId(), portletId);

      if (portlet == null) {
        _log.error("Portlet " + portletId + " cannot be removed because it is not registered");

        return;
      }

      PermissionChecker permissionChecker = PermissionThreadLocal.getPermissionChecker();

      if (!LayoutPermissionUtil.contains(permissionChecker, getLayout(), ActionKeys.UPDATE)
          && !isCustomizable()) {

        return;
      }
    } catch (Exception e) {
      _log.error(e, e);

      return;
    }

    List<String> columns = getColumns();

    for (int i = 0; i < columns.size(); i++) {
      String columnId = columns.get(i);

      if (isCustomizable() && isColumnDisabled(columnId)) {
        continue;
      }

      String columnValue = StringPool.BLANK;

      if (hasUserPreferences()) {
        columnValue = getUserPreference(columnId);
      } else {
        columnValue = getTypeSettingsProperty(columnId);
      }

      columnValue = StringUtil.removeFromList(columnValue, portletId);

      if (hasUserPreferences()) {
        setUserPreference(columnId, columnValue);
      } else {
        setTypeSettingsProperty(columnId, columnValue);
      }
    }

    if (cleanUp) {
      try {
        onRemoveFromLayout(new String[] {portletId});
      } catch (Exception e) {
        _log.error(e, e);
      }
    }
  }
  public List<Layout> getChildren(PermissionChecker permissionChecker)
      throws PortalException, SystemException {

    List<Layout> layouts = ListUtil.copy(getChildren());

    Iterator<Layout> itr = layouts.iterator();

    while (itr.hasNext()) {
      Layout layout = itr.next();

      if (layout.isHidden()
          || !LayoutPermissionUtil.contains(permissionChecker, layout, ActionKeys.VIEW)) {

        itr.remove();
      }
    }

    return layouts;
  }
  private void _doRender(HttpServletRequest request, HttpServletResponse response, Portlet portlet)
      throws Exception {

    if ((portlet != null) && portlet.isInstanceable() && !portlet.isAddDefaultResource()) {

      String instanceId = portlet.getInstanceId();

      if (!Validator.isPassword(instanceId)) {
        if (_log.isDebugEnabled()) {
          _log.debug(
              "Portlet "
                  + portlet.getPortletId()
                  + " is instanceable but does not have a valid "
                  + "instance id");
        }

        portlet = null;
      }
    }

    if (portlet == null) {
      return;
    }

    // Capture the current portlet's settings to reset them once the child
    // portlet is rendered

    ThemeDisplay themeDisplay = (ThemeDisplay) request.getAttribute(WebKeys.THEME_DISPLAY);

    PortletDisplay portletDisplay = themeDisplay.getPortletDisplay();

    PortletDisplay portletDisplayClone = PortletDisplayFactory.create();

    portletDisplay.copyTo(portletDisplayClone);

    PortletConfig portletConfig =
        (PortletConfig) request.getAttribute(JavaConstants.JAVAX_PORTLET_CONFIG);

    PortletRequest portletRequest =
        (PortletRequest) request.getAttribute(JavaConstants.JAVAX_PORTLET_REQUEST);

    if (!(portletRequest instanceof RenderRequest)) {
      portletRequest = null;
    }

    PortletResponse portletResponse =
        (PortletResponse) request.getAttribute(JavaConstants.JAVAX_PORTLET_RESPONSE);

    if (!(portletResponse instanceof RenderResponse)) {
      portletResponse = null;
    }

    String lifecycle = (String) request.getAttribute(PortletRequest.LIFECYCLE_PHASE);

    request.setAttribute(WebKeys.RENDER_PORTLET, portlet);

    String path = (String) request.getAttribute(WebKeys.RENDER_PATH);

    if (path == null) {
      path = "/html/portal/render_portlet.jsp";
    }

    RequestDispatcher requestDispatcher =
        DirectRequestDispatcherFactoryUtil.getRequestDispatcher(request, path);

    BufferCacheServletResponse bufferCacheServletResponse = null;

    boolean writeOutput = false;

    if (response instanceof BufferCacheServletResponse) {
      bufferCacheServletResponse = (BufferCacheServletResponse) response;
    } else {
      writeOutput = true;
      bufferCacheServletResponse = new BufferCacheServletResponse(response);
    }

    try {
      requestDispatcher.include(request, bufferCacheServletResponse);

      Boolean portletConfiguratorVisibility =
          (Boolean) request.getAttribute(WebKeys.PORTLET_CONFIGURATOR_VISIBILITY);

      if (portletConfiguratorVisibility != null) {
        request.removeAttribute(WebKeys.PORTLET_CONFIGURATOR_VISIBILITY);

        Layout layout = themeDisplay.getLayout();

        if (!layout.isTypeControlPanel()
            && !LayoutPermissionUtil.contains(
                themeDisplay.getPermissionChecker(), layout, ActionKeys.UPDATE)
            && !PortletPermissionUtil.contains(
                themeDisplay.getPermissionChecker(),
                layout,
                portlet.getPortletId(),
                ActionKeys.CONFIGURATION)) {

          bufferCacheServletResponse.setCharBuffer(null);

          return;
        }
      }

      if (writeOutput) {
        Writer writer = response.getWriter();

        writer.write(bufferCacheServletResponse.getString());
      }
    } finally {
      portletDisplay.copyFrom(portletDisplayClone);

      portletDisplayClone.recycle();

      if (portletConfig != null) {
        request.setAttribute(JavaConstants.JAVAX_PORTLET_CONFIG, portletConfig);
      }

      if (portletRequest != null) {
        request.setAttribute(JavaConstants.JAVAX_PORTLET_REQUEST, portletRequest);
      }

      if (portletResponse != null) {
        request.setAttribute(JavaConstants.JAVAX_PORTLET_RESPONSE, portletResponse);
      }

      if (lifecycle != null) {
        request.setAttribute(PortletRequest.LIFECYCLE_PHASE, lifecycle);
      }

      request.removeAttribute(WebKeys.RENDER_PORTLET);
    }
  }
  public boolean isShowSite(PermissionChecker permissionChecker, boolean privateSite)
      throws PortalException, SystemException {

    if (!isControlPanel() && !isSite() && !isUser()) {
      return false;
    }

    boolean showSite = true;

    Layout defaultLayout = null;

    int siteLayoutsCount = LayoutLocalServiceUtil.getLayoutsCount(this, true);

    if (siteLayoutsCount == 0) {
      boolean hasPowerUserRole =
          RoleLocalServiceUtil.hasUserRole(
              permissionChecker.getUserId(),
              permissionChecker.getCompanyId(),
              RoleConstants.POWER_USER,
              true);

      if (isSite()) {
        if (privateSite) {
          showSite = PropsValues.MY_SITES_SHOW_PRIVATE_SITES_WITH_NO_LAYOUTS;
        } else {
          showSite = PropsValues.MY_SITES_SHOW_PUBLIC_SITES_WITH_NO_LAYOUTS;
        }
      } else if (isOrganization()) {
        showSite = false;
      } else if (isUser()) {
        if (privateSite) {
          showSite = PropsValues.MY_SITES_SHOW_USER_PRIVATE_SITES_WITH_NO_LAYOUTS;

          if (PropsValues.LAYOUT_USER_PRIVATE_LAYOUTS_POWER_USER_REQUIRED && !hasPowerUserRole) {

            showSite = false;
          }
        } else {
          showSite = PropsValues.MY_SITES_SHOW_USER_PUBLIC_SITES_WITH_NO_LAYOUTS;

          if (PropsValues.LAYOUT_USER_PUBLIC_LAYOUTS_POWER_USER_REQUIRED && !hasPowerUserRole) {

            showSite = false;
          }
        }
      }
    } else {
      defaultLayout =
          LayoutLocalServiceUtil.fetchFirstLayout(
              getGroupId(), privateSite, LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);

      if ((defaultLayout != null)
          && !LayoutPermissionUtil.contains(
              permissionChecker, defaultLayout, true, ActionKeys.VIEW)) {

        showSite = false;
      } else if (isOrganization() && !isSite()) {
        _log.error("Group " + getGroupId() + " is an organization site that does not have pages");
      }
    }

    return showSite;
  }
  public void removePortletId(long userId, String portletId, boolean cleanUp) {

    try {
      Portlet portlet = PortletLocalServiceUtil.getPortletById(getCompanyId(), portletId);

      if (portlet == null) {
        _log.error("Portlet " + portletId + " cannot be removed because it is not registered");

        return;
      }

      PermissionChecker permissionChecker = PermissionThreadLocal.getPermissionChecker();

      if (!LayoutPermissionUtil.contains(permissionChecker, getLayout(), ActionKeys.UPDATE)
          && !isCustomizable()) {

        return;
      }
    } catch (Exception e) {
      _log.error(e, e);
    }

    List<String> columns = getColumns();

    for (int i = 0; i < columns.size(); i++) {
      String columnId = columns.get(i);

      if (isCustomizable() && isColumnDisabled(columnId)) {
        continue;
      }

      String columnValue = StringPool.BLANK;

      if (hasUserPreferences()) {
        columnValue = getUserPreference(columnId);
      } else {
        columnValue = getTypeSettingsProperties().getProperty(columnId);
      }

      columnValue = StringUtil.remove(columnValue, portletId);

      if (hasUserPreferences()) {
        setUserPreference(columnId, columnValue);

        try {
          String rootPortletId = PortletConstants.getRootPortletId(portletId);

          ResourceLocalServiceUtil.deleteResource(
              getCompanyId(),
              rootPortletId,
              ResourceConstants.SCOPE_INDIVIDUAL,
              PortletPermissionUtil.getPrimaryKey(getPlid(), portletId));
        } catch (Exception e) {
        }
      } else {
        getTypeSettingsProperties().setProperty(columnId, columnValue);
      }
    }

    if (cleanUp) {
      removeStatesPortletId(portletId);
      removeModesPortletId(portletId);

      try {
        onRemoveFromLayout(portletId);
      } catch (Exception e) {
        _log.error("Unable to fire portlet layout listener event", e);
      }
    }
  }
  @Override
  public PortletPreferencesIds getPortletPreferencesIds(
      long siteGroupId, long userId, Layout layout, String portletId, boolean modeEditGuest)
      throws PortalException {

    PermissionChecker permissionChecker = PermissionThreadLocal.getPermissionChecker();

    String originalPortletId = portletId;

    Portlet portlet = PortletLocalServiceUtil.getPortletById(layout.getCompanyId(), portletId);

    long ownerId = 0;
    int ownerType = 0;
    long plid = 0;

    if (modeEditGuest) {
      boolean hasUpdateLayoutPermission =
          LayoutPermissionUtil.contains(permissionChecker, layout, ActionKeys.UPDATE);

      if (!layout.isPrivateLayout() && hasUpdateLayoutPermission) {
      } else {

        // Only users with the correct permissions can update guest
        // preferences

        throw new PrincipalException();
      }
    }

    if (PortletConstants.hasUserId(originalPortletId)
        && (PortletConstants.getUserId(originalPortletId) == userId)) {

      ownerId = userId;
      ownerType = PortletKeys.PREFS_OWNER_TYPE_USER;
      plid = layout.getPlid();
    } else if (portlet.isPreferencesCompanyWide()) {
      ownerId = layout.getCompanyId();
      ownerType = PortletKeys.PREFS_OWNER_TYPE_COMPANY;
      plid = PortletKeys.PREFS_PLID_SHARED;
      portletId = PortletConstants.getRootPortletId(portletId);
    } else {
      if (portlet.isPreferencesUniquePerLayout()) {
        ownerId = PortletKeys.PREFS_OWNER_ID_DEFAULT;
        ownerType = PortletKeys.PREFS_OWNER_TYPE_LAYOUT;
        plid = layout.getPlid();

        if (portlet.isPreferencesOwnedByGroup()) {
        } else {
          if ((userId <= 0) || modeEditGuest) {
            userId = UserLocalServiceUtil.getDefaultUserId(layout.getCompanyId());
          }

          ownerId = userId;
          ownerType = PortletKeys.PREFS_OWNER_TYPE_USER;
        }
      } else {
        plid = PortletKeys.PREFS_PLID_SHARED;

        if (portlet.isPreferencesOwnedByGroup()) {
          ownerId = siteGroupId;
          ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
          portletId = PortletConstants.getRootPortletId(portletId);
        } else {
          if ((userId <= 0) || modeEditGuest) {
            userId = UserLocalServiceUtil.getDefaultUserId(layout.getCompanyId());
          }

          ownerId = userId;
          ownerType = PortletKeys.PREFS_OWNER_TYPE_USER;
        }
      }
    }

    return new PortletPreferencesIds(layout.getCompanyId(), ownerId, ownerType, plid, portletId);
  }