@Before
  public void setUp() throws Exception {

    // Create site template

    FinderCacheUtil.clearCache();

    LayoutSetPrototype layoutSetPrototype =
        ServiceTestUtil.addLayoutSetPrototype(ServiceTestUtil.randomString());

    _layoutSetPrototypeGroup = layoutSetPrototype.getGroup();

    _layoutSetPrototypeLayout =
        ServiceTestUtil.addLayout(
            _layoutSetPrototypeGroup.getGroupId(), ServiceTestUtil.randomString(), true);

    updateLayoutTemplateId(_layoutSetPrototypeLayout, "1_column");

    _layoutSetPrototypeJournalArticle =
        addJournalArticle(_layoutSetPrototypeGroup.getGroupId(), 0, "Test Article", "Test Content");

    _layoutSetPrototypeJournalContentPortletId =
        addJournalContentPortletToLayout(
            TestPropsValues.getUserId(),
            _layoutSetPrototypeLayout,
            _layoutSetPrototypeJournalArticle,
            "column-1");

    // Create site from site template

    _group = ServiceTestUtil.addGroup(ServiceTestUtil.randomString());

    SitesUtil.updateLayoutSetPrototypesLinks(
        _group, layoutSetPrototype.getLayoutSetPrototypeId(), 0, true, true);

    propagateChanges(_group);
  }
  protected Object[] updateGroup(ActionRequest actionRequest) throws Exception {

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

    long userId = PortalUtil.getUserId(actionRequest);

    long liveGroupId = ParamUtil.getLong(actionRequest, "liveGroupId");

    long parentGroupId =
        ParamUtil.getLong(
            actionRequest,
            "parentGroupSearchContainerPrimaryKeys",
            GroupConstants.DEFAULT_PARENT_GROUP_ID);
    String name = null;
    String description = null;
    int type = 0;
    String friendlyURL = null;
    boolean active = false;

    ServiceContext serviceContext =
        ServiceContextFactory.getInstance(Group.class.getName(), actionRequest);

    Group liveGroup = null;
    String oldFriendlyURL = null;
    String oldStagingFriendlyURL = null;

    if (liveGroupId <= 0) {

      // Add group

      name = ParamUtil.getString(actionRequest, "name");
      description = ParamUtil.getString(actionRequest, "description");
      type = ParamUtil.getInteger(actionRequest, "type");
      friendlyURL = ParamUtil.getString(actionRequest, "friendlyURL");
      active = ParamUtil.getBoolean(actionRequest, "active");

      liveGroup =
          GroupServiceUtil.addGroup(
              parentGroupId,
              GroupConstants.DEFAULT_LIVE_GROUP_ID,
              name,
              description,
              type,
              friendlyURL,
              true,
              active,
              serviceContext);

      LiveUsers.joinGroup(themeDisplay.getCompanyId(), liveGroup.getGroupId(), userId);
    } else {

      // Update group

      liveGroup = GroupLocalServiceUtil.getGroup(liveGroupId);

      oldFriendlyURL = liveGroup.getFriendlyURL();

      name = ParamUtil.getString(actionRequest, "name", liveGroup.getName());
      description = ParamUtil.getString(actionRequest, "description", liveGroup.getDescription());
      type = ParamUtil.getInteger(actionRequest, "type", liveGroup.getType());
      friendlyURL = ParamUtil.getString(actionRequest, "friendlyURL", liveGroup.getFriendlyURL());
      active = ParamUtil.getBoolean(actionRequest, "active", liveGroup.getActive());

      liveGroup =
          GroupServiceUtil.updateGroup(
              liveGroupId,
              parentGroupId,
              name,
              description,
              type,
              friendlyURL,
              active,
              serviceContext);

      if (type == GroupConstants.TYPE_SITE_OPEN) {
        List<MembershipRequest> membershipRequests =
            MembershipRequestLocalServiceUtil.search(
                liveGroupId,
                MembershipRequestConstants.STATUS_PENDING,
                QueryUtil.ALL_POS,
                QueryUtil.ALL_POS);

        for (MembershipRequest membershipRequest : membershipRequests) {
          MembershipRequestServiceUtil.updateStatus(
              membershipRequest.getMembershipRequestId(),
              themeDisplay.translate("your-membership-has-been-approved"),
              MembershipRequestConstants.STATUS_APPROVED,
              serviceContext);

          LiveUsers.joinGroup(
              themeDisplay.getCompanyId(),
              membershipRequest.getGroupId(),
              new long[] {membershipRequest.getUserId()});
        }
      }
    }

    // Settings

    UnicodeProperties typeSettingsProperties = liveGroup.getTypeSettingsProperties();

    String customJspServletContextName =
        ParamUtil.getString(
            actionRequest,
            "customJspServletContextName",
            typeSettingsProperties.getProperty("customJspServletContextName"));

    typeSettingsProperties.setProperty("customJspServletContextName", customJspServletContextName);

    typeSettingsProperties.setProperty(
        "defaultSiteRoleIds",
        ListUtil.toString(getRoles(actionRequest), Role.ROLE_ID_ACCESSOR, StringPool.COMMA));
    typeSettingsProperties.setProperty(
        "defaultTeamIds",
        ListUtil.toString(getTeams(actionRequest), Team.TEAM_ID_ACCESSOR, StringPool.COMMA));

    String[] analyticsTypes =
        PrefsPropsUtil.getStringArray(
            themeDisplay.getCompanyId(), PropsKeys.ADMIN_ANALYTICS_TYPES, StringPool.NEW_LINE);

    for (String analyticsType : analyticsTypes) {
      if (analyticsType.equalsIgnoreCase("google")) {
        String googleAnalyticsId =
            ParamUtil.getString(
                actionRequest,
                "googleAnalyticsId",
                typeSettingsProperties.getProperty("googleAnalyticsId"));

        typeSettingsProperties.setProperty("googleAnalyticsId", googleAnalyticsId);
      } else {
        String analyticsScript =
            ParamUtil.getString(
                actionRequest,
                SitesUtil.ANALYTICS_PREFIX + analyticsType,
                typeSettingsProperties.getProperty(analyticsType));

        typeSettingsProperties.setProperty(
            SitesUtil.ANALYTICS_PREFIX + analyticsType, analyticsScript);
      }
    }

    String publicRobots =
        ParamUtil.getString(
            actionRequest, "publicRobots", liveGroup.getTypeSettingsProperty("false-robots.txt"));
    String privateRobots =
        ParamUtil.getString(
            actionRequest, "privateRobots", liveGroup.getTypeSettingsProperty("true-robots.txt"));

    typeSettingsProperties.setProperty("false-robots.txt", publicRobots);
    typeSettingsProperties.setProperty("true-robots.txt", privateRobots);

    int trashEnabled =
        ParamUtil.getInteger(
            actionRequest,
            "trashEnabled",
            GetterUtil.getInteger(typeSettingsProperties.getProperty("trashEnabled")));

    typeSettingsProperties.setProperty("trashEnabled", String.valueOf(trashEnabled));

    int trashEntriesMaxAgeCompany =
        PrefsPropsUtil.getInteger(themeDisplay.getCompanyId(), PropsKeys.TRASH_ENTRIES_MAX_AGE);

    int defaultTrashEntriesMaxAgeGroup =
        GetterUtil.getInteger(
            typeSettingsProperties.getProperty("trashEntriesMaxAge"), trashEntriesMaxAgeCompany);

    int trashEntriesMaxAgeGroup =
        ParamUtil.getInteger(actionRequest, "trashEntriesMaxAge", defaultTrashEntriesMaxAgeGroup);

    if (trashEntriesMaxAgeGroup != trashEntriesMaxAgeCompany) {
      typeSettingsProperties.setProperty(
          "trashEntriesMaxAge", String.valueOf(trashEntriesMaxAgeGroup));
    } else {
      typeSettingsProperties.remove("trashEntriesMaxAge");
    }

    // Virtual hosts

    LayoutSet publicLayoutSet = liveGroup.getPublicLayoutSet();

    String publicVirtualHost =
        ParamUtil.getString(
            actionRequest, "publicVirtualHost", publicLayoutSet.getVirtualHostname());

    LayoutSetServiceUtil.updateVirtualHost(liveGroup.getGroupId(), false, publicVirtualHost);

    LayoutSet privateLayoutSet = liveGroup.getPrivateLayoutSet();

    String privateVirtualHost =
        ParamUtil.getString(
            actionRequest, "privateVirtualHost", privateLayoutSet.getVirtualHostname());

    LayoutSetServiceUtil.updateVirtualHost(liveGroup.getGroupId(), true, privateVirtualHost);

    // Staging

    if (liveGroup.hasStagingGroup()) {
      Group stagingGroup = liveGroup.getStagingGroup();

      oldStagingFriendlyURL = stagingGroup.getFriendlyURL();

      friendlyURL =
          ParamUtil.getString(actionRequest, "stagingFriendlyURL", stagingGroup.getFriendlyURL());

      GroupServiceUtil.updateFriendlyURL(stagingGroup.getGroupId(), friendlyURL);

      LayoutSet stagingPublicLayoutSet = stagingGroup.getPublicLayoutSet();

      publicVirtualHost =
          ParamUtil.getString(
              actionRequest,
              "stagingPublicVirtualHost",
              stagingPublicLayoutSet.getVirtualHostname());

      LayoutSetServiceUtil.updateVirtualHost(stagingGroup.getGroupId(), false, publicVirtualHost);

      LayoutSet stagingPrivateLayoutSet = stagingGroup.getPrivateLayoutSet();

      privateVirtualHost =
          ParamUtil.getString(
              actionRequest,
              "stagingPrivateVirtualHost",
              stagingPrivateLayoutSet.getVirtualHostname());

      LayoutSetServiceUtil.updateVirtualHost(stagingGroup.getGroupId(), true, privateVirtualHost);
    }

    liveGroup =
        GroupServiceUtil.updateGroup(liveGroup.getGroupId(), typeSettingsProperties.toString());

    // Layout set prototypes

    if (!liveGroup.isStaged()) {
      long privateLayoutSetPrototypeId =
          ParamUtil.getLong(actionRequest, "privateLayoutSetPrototypeId");
      long publicLayoutSetPrototypeId =
          ParamUtil.getLong(actionRequest, "publicLayoutSetPrototypeId");

      boolean privateLayoutSetPrototypeLinkEnabled =
          ParamUtil.getBoolean(
              actionRequest,
              "privateLayoutSetPrototypeLinkEnabled",
              privateLayoutSet.isLayoutSetPrototypeLinkEnabled());
      boolean publicLayoutSetPrototypeLinkEnabled =
          ParamUtil.getBoolean(
              actionRequest,
              "publicLayoutSetPrototypeLinkEnabled",
              publicLayoutSet.isLayoutSetPrototypeLinkEnabled());

      if ((privateLayoutSetPrototypeId == 0)
          && (publicLayoutSetPrototypeId == 0)
          && !privateLayoutSetPrototypeLinkEnabled
          && !publicLayoutSetPrototypeLinkEnabled) {

        long layoutSetPrototypeId = ParamUtil.getLong(actionRequest, "layoutSetPrototypeId");
        int layoutSetVisibility = ParamUtil.getInteger(actionRequest, "layoutSetVisibility");
        boolean layoutSetPrototypeLinkEnabled =
            ParamUtil.getBoolean(
                actionRequest, "layoutSetPrototypeLinkEnabled", (layoutSetPrototypeId > 0));

        if (layoutSetVisibility == _LAYOUT_SET_VISIBILITY_PRIVATE) {
          privateLayoutSetPrototypeId = layoutSetPrototypeId;

          privateLayoutSetPrototypeLinkEnabled = layoutSetPrototypeLinkEnabled;
        } else {
          publicLayoutSetPrototypeId = layoutSetPrototypeId;

          publicLayoutSetPrototypeLinkEnabled = layoutSetPrototypeLinkEnabled;
        }
      }

      SitesUtil.updateLayoutSetPrototypesLinks(
          liveGroup,
          publicLayoutSetPrototypeId,
          privateLayoutSetPrototypeId,
          publicLayoutSetPrototypeLinkEnabled,
          privateLayoutSetPrototypeLinkEnabled);
    }

    // Staging

    String redirect = ParamUtil.getString(actionRequest, "redirect");

    long refererPlid = GetterUtil.getLong(HttpUtil.getParameter(redirect, "refererPlid", false));

    if (!privateLayoutSet.isLayoutSetPrototypeLinkActive()
        && !publicLayoutSet.isLayoutSetPrototypeLinkActive()) {

      if ((refererPlid > 0)
          && liveGroup.hasStagingGroup()
          && (themeDisplay.getScopeGroupId() != liveGroup.getGroupId())) {

        Layout firstLayout =
            LayoutLocalServiceUtil.fetchFirstLayout(
                liveGroup.getGroupId(), false, LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);

        if (firstLayout == null) {
          firstLayout =
              LayoutLocalServiceUtil.fetchFirstLayout(
                  liveGroup.getGroupId(), true, LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
        }

        if (firstLayout != null) {
          refererPlid = firstLayout.getPlid();
        } else {
          refererPlid = 0;
        }
      }

      StagingUtil.updateStaging(actionRequest, liveGroup);
    }

    return new Object[] {liveGroup, oldFriendlyURL, oldStagingFriendlyURL, refererPlid};
  }
  protected void runLayoutSetPrototype(
      boolean layoutSetLinkEnabled,
      boolean layoutLinkEnabled,
      boolean addPage,
      boolean deletePage,
      boolean useLayoutPrototype)
      throws Exception {

    LayoutSetPrototype layoutSetPrototype =
        ServiceTestUtil.addLayoutSetPrototype(ServiceTestUtil.randomString());

    Group layoutSetPrototypeGroup = layoutSetPrototype.getGroup();

    int layoutSetPrototypeLayoutsCount =
        LayoutLocalServiceUtil.getLayoutsCount(layoutSetPrototypeGroup, true);

    ServiceTestUtil.addLayout(
        layoutSetPrototypeGroup.getGroupId(), ServiceTestUtil.randomString(), true);
    ServiceTestUtil.addLayout(
        layoutSetPrototypeGroup.getGroupId(), ServiceTestUtil.randomString(), true);

    Group group = ServiceTestUtil.addGroup();

    SitesUtil.updateLayoutSetPrototypesLinks(
        group, layoutSetPrototype.getLayoutSetPrototypeId(), 0, layoutSetLinkEnabled, false);

    propagateChanges(group);

    int groupLayoutsCount = LayoutLocalServiceUtil.getLayoutsCount(group, false);

    Assert.assertEquals(groupLayoutsCount, layoutSetPrototypeLayoutsCount + 2);

    if (addPage) {
      Layout layout = null;

      if (useLayoutPrototype) {
        LayoutPrototype layoutPrototype =
            ServiceTestUtil.addLayoutPrototype(ServiceTestUtil.randomString());

        Layout layoutPrototypeLayout = layoutPrototype.getLayout();

        updateLayoutTemplateId(layoutPrototypeLayout, "2_2_columns");

        layout =
            addLayout(
                group.getGroupId(),
                ServiceTestUtil.randomString(),
                layoutPrototype,
                layoutLinkEnabled);

        if (layoutLinkEnabled) {
          layout = propagateChanges(layout);
        }

        updateLayoutTemplateId(layoutPrototypeLayout, "1_column");

        if (layoutLinkEnabled) {
          Assert.assertEquals(
              "2_2_columns",
              layout.getTypeSettingsProperty(LayoutTypePortletConstants.LAYOUT_TEMPLATE_ID));

          layout = propagateChanges(layout);
        }
      } else {

        // Database will store Date values without milliseconds. Wait
        // for more than one second to ensure that later queries can
        // correctly compare the Date values.

        Thread.sleep(2000);

        layout =
            ServiceTestUtil.addLayout(
                layoutSetPrototypeGroup.getGroupId(), ServiceTestUtil.randomString(), true);
      }

      if (!useLayoutPrototype) {
        groupLayoutsCount = LayoutLocalServiceUtil.getLayoutsCount(group, false);

        Assert.assertEquals(groupLayoutsCount, layoutSetPrototypeLayoutsCount + 2);
      }

      propagateChanges(group);

      groupLayoutsCount = LayoutLocalServiceUtil.getLayoutsCount(group, false);

      if (layoutSetLinkEnabled) {
        Assert.assertEquals(groupLayoutsCount, layoutSetPrototypeLayoutsCount + 3);

        if (useLayoutPrototype) {
          if (layoutLinkEnabled) {
            Assert.assertEquals(
                "1_column",
                layout.getTypeSettingsProperty(LayoutTypePortletConstants.LAYOUT_TEMPLATE_ID));
          } else {
            Assert.assertEquals(
                "2_2_columns",
                layout.getTypeSettingsProperty(LayoutTypePortletConstants.LAYOUT_TEMPLATE_ID));
          }
        }
      }

      if (deletePage) {
        LayoutLocalServiceUtil.deleteLayout(layout, true, ServiceTestUtil.getServiceContext());

        groupLayoutsCount = LayoutLocalServiceUtil.getLayoutsCount(group, false);

        if (layoutSetLinkEnabled) {
          if (!useLayoutPrototype) {
            Assert.assertEquals(groupLayoutsCount, layoutSetPrototypeLayoutsCount + 3);

            propagateChanges(group);
          }

          groupLayoutsCount = LayoutLocalServiceUtil.getLayoutsCount(group, false);
        }

        Assert.assertEquals(groupLayoutsCount, layoutSetPrototypeLayoutsCount + 2);
      }
    }
  }
  protected Organization updateOrganization(ActionRequest actionRequest) throws Exception {

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

    long organizationId = ParamUtil.getLong(actionRequest, "organizationId");

    long parentOrganizationId =
        ParamUtil.getLong(
            actionRequest,
            "parentOrganizationSearchContainerPrimaryKeys",
            OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID);
    String name = ParamUtil.getString(actionRequest, "name");
    int statusId = ParamUtil.getInteger(actionRequest, "statusId");
    String type = ParamUtil.getString(actionRequest, "type");
    long regionId = ParamUtil.getLong(actionRequest, "regionId");
    long countryId = ParamUtil.getLong(actionRequest, "countryId");
    String comments = ParamUtil.getString(actionRequest, "comments");
    boolean deleteLogo = ParamUtil.getBoolean(actionRequest, "deleteLogo");

    byte[] logoBytes = null;

    long fileEntryId = ParamUtil.getLong(actionRequest, "fileEntryId");

    if (fileEntryId > 0) {
      FileEntry fileEntry = DLAppLocalServiceUtil.getFileEntry(fileEntryId);

      logoBytes = FileUtil.getBytes(fileEntry.getContentStream());
    }

    boolean site = ParamUtil.getBoolean(actionRequest, "site");
    List<Address> addresses = UsersAdminUtil.getAddresses(actionRequest);
    List<EmailAddress> emailAddresses = UsersAdminUtil.getEmailAddresses(actionRequest);
    List<OrgLabor> orgLabors = UsersAdminUtil.getOrgLabors(actionRequest);
    List<Phone> phones = UsersAdminUtil.getPhones(actionRequest);
    List<Website> websites = UsersAdminUtil.getWebsites(actionRequest);

    ServiceContext serviceContext =
        ServiceContextFactory.getInstance(Organization.class.getName(), actionRequest);

    Organization organization = null;

    if (organizationId <= 0) {

      // Add organization

      organization =
          OrganizationServiceUtil.addOrganization(
              parentOrganizationId,
              name,
              type,
              regionId,
              countryId,
              statusId,
              comments,
              site,
              addresses,
              emailAddresses,
              orgLabors,
              phones,
              websites,
              serviceContext);
    } else {

      // Update organization

      organization =
          OrganizationServiceUtil.updateOrganization(
              organizationId,
              parentOrganizationId,
              name,
              type,
              regionId,
              countryId,
              statusId,
              comments,
              !deleteLogo,
              logoBytes,
              site,
              addresses,
              emailAddresses,
              orgLabors,
              phones,
              websites,
              serviceContext);
    }

    // Layout set prototypes

    long publicLayoutSetPrototypeId =
        ParamUtil.getLong(actionRequest, "publicLayoutSetPrototypeId");
    long privateLayoutSetPrototypeId =
        ParamUtil.getLong(actionRequest, "privateLayoutSetPrototypeId");
    boolean publicLayoutSetPrototypeLinkEnabled =
        ParamUtil.getBoolean(
            actionRequest, "publicLayoutSetPrototypeLinkEnabled", (publicLayoutSetPrototypeId > 0));
    boolean privateLayoutSetPrototypeLinkEnabled =
        ParamUtil.getBoolean(
            actionRequest,
            "privateLayoutSetPrototypeLinkEnabled",
            (privateLayoutSetPrototypeId > 0));

    Group organizationGroup = organization.getGroup();

    if (GroupPermissionUtil.contains(
        themeDisplay.getPermissionChecker(), organizationGroup, ActionKeys.UPDATE)) {

      SitesUtil.updateLayoutSetPrototypesLinks(
          organizationGroup,
          publicLayoutSetPrototypeId,
          privateLayoutSetPrototypeId,
          publicLayoutSetPrototypeLinkEnabled,
          privateLayoutSetPrototypeLinkEnabled);
    }

    // Reminder queries

    String reminderQueries = actionRequest.getParameter("reminderQueries");

    PortletPreferences portletPreferences = organization.getPreferences();

    LocalizationUtil.setLocalizedPreferencesValues(
        actionRequest, portletPreferences, "reminderQueries");

    portletPreferences.setValue("reminderQueries", reminderQueries);

    portletPreferences.store();

    return organization;
  }