@Test
  public void testExportImportLayoutsPriorities() throws Exception {
    Layout layout1 = LayoutTestUtil.addLayout(group);
    Layout layout2 = LayoutTestUtil.addLayout(group);
    Layout layout3 = LayoutTestUtil.addLayout(group);

    int priority = layout1.getPriority();

    layout1.setPriority(layout3.getPriority());
    layout3.setPriority(priority);

    layout1 = LayoutLocalServiceUtil.updateLayout(layout1);
    layout3 = LayoutLocalServiceUtil.updateLayout(layout3);

    long[] layoutIds = new long[] {layout1.getLayoutId(), layout2.getLayoutId()};

    exportImportLayouts(layoutIds, getImportParameterMap());

    Layout importedLayout1 =
        LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
            layout1.getUuid(), importedGroup.getGroupId(), false);

    Assert.assertNotEquals(layout1.getPriority(), importedLayout1.getPriority());

    Layout importedLayout2 =
        LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
            layout2.getUuid(), importedGroup.getGroupId(), false);

    Assert.assertNotEquals(layout2.getPriority(), importedLayout2.getPriority());

    List<Layout> layouts = LayoutLocalServiceUtil.getLayouts(group.getGroupId(), false);

    layoutIds = ExportImportHelperUtil.getLayoutIds(layouts);

    exportImportLayouts(layoutIds, getImportParameterMap());

    importedLayout1 =
        LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
            layout1.getUuid(), importedGroup.getGroupId(), false);

    Assert.assertEquals(layout1.getPriority(), importedLayout1.getPriority());

    importedLayout2 =
        LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
            layout2.getUuid(), importedGroup.getGroupId(), false);

    Assert.assertEquals(layout2.getPriority(), importedLayout2.getPriority());

    Layout importedLayout3 =
        LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
            layout3.getUuid(), importedGroup.getGroupId(), false);

    Assert.assertEquals(layout3.getPriority(), importedLayout3.getPriority());
  }
  protected void validatePrototypedLayouts(Class<?> clazz, long groupId) throws Exception {

    List<Layout> layouts = getLayouts(clazz);

    for (Layout layout : layouts) {
      Layout importedLayout =
          LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
              layout.getUuid(), groupId, layout.getPrivateLayout());

      Assert.assertNotNull(importedLayout);
      Assert.assertEquals(
          layout.getTypeSettingsProperty(
              LayoutSetPrototypeStagedModelDataHandlerTest.class.getName()),
          importedLayout.getTypeSettingsProperty(
              LayoutSetPrototypeStagedModelDataHandlerTest.class.getName()));
    }

    List<LayoutFriendlyURL> layoutFriendlyURLs = getLayoutFriendlyURLs(clazz);

    for (LayoutFriendlyURL layoutFriendlyURL : layoutFriendlyURLs) {
      LayoutFriendlyURL importedLayoutFriendlyURL =
          LayoutFriendlyURLLocalServiceUtil.fetchLayoutFriendlyURLByUuidAndGroupId(
              layoutFriendlyURL.getUuid(), groupId);

      Assert.assertNotNull(importedLayoutFriendlyURL);
      Assert.assertEquals(
          layoutFriendlyURL.getFriendlyURL(), importedLayoutFriendlyURL.getFriendlyURL());
    }
  }
 @Override
 protected StagedModel getStagedModel(String uuid, Group group) {
   try {
     return LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(uuid, group.getGroupId(), false);
   } catch (Exception e) {
     return null;
   }
 }
  @Test
  public void testDeleteMissingLayouts() throws Exception {
    Layout layout1 = LayoutTestUtil.addLayout(group);
    Layout layout2 = LayoutTestUtil.addLayout(group);

    List<Layout> layouts = LayoutLocalServiceUtil.getLayouts(group.getGroupId(), false);

    long[] layoutIds = ExportImportHelperUtil.getLayoutIds(layouts);

    exportImportLayouts(layoutIds, getImportParameterMap());

    Assert.assertEquals(
        LayoutLocalServiceUtil.getLayoutsCount(group, false),
        LayoutLocalServiceUtil.getLayoutsCount(importedGroup, false));

    LayoutTestUtil.addLayout(importedGroup);

    Map<String, String[]> parameterMap = getImportParameterMap();

    parameterMap.put(
        PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS, new String[] {Boolean.TRUE.toString()});

    layoutIds = new long[] {layout1.getLayoutId()};

    exportImportLayouts(layoutIds, getImportParameterMap());

    Assert.assertEquals(
        LayoutLocalServiceUtil.getLayoutsCount(group, false),
        LayoutLocalServiceUtil.getLayoutsCount(importedGroup, false));

    Layout importedLayout1 =
        LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
            layout1.getUuid(), importedGroup.getGroupId(), false);

    Assert.assertNotNull(importedLayout1);

    Layout importedLayout2 =
        LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
            layout2.getUuid(), importedGroup.getGroupId(), false);

    Assert.assertNotNull(importedLayout2);
  }
  @Ignore
  @Test
  public void testImportLinksToLayoutsIdsReplacement() throws Exception {
    LayoutTestUtil.addLayout(_liveGroup, true);
    LayoutTestUtil.addLayout(_liveGroup, false);

    exportImportLayouts(true);
    exportImportLayouts(false);

    Layout importedPrivateLayout =
        LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
            _stagingPrivateLayout.getUuid(), _liveGroup.getGroupId(), true);
    Layout importedPublicLayout =
        LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
            _stagingPublicLayout.getUuid(), _liveGroup.getGroupId(), false);

    Map<Long, Long> layoutPlids =
        (Map<Long, Long>) _portletDataContextImport.getNewPrimaryKeysMap(Layout.class);

    layoutPlids.put(_stagingPrivateLayout.getPlid(), importedPrivateLayout.getPlid());
    layoutPlids.put(_stagingPublicLayout.getPlid(), importedPublicLayout.getPlid());

    String content = getContent("layout_links_ids_replacement.txt");

    String expectedContent =
        replaceLinksToLayoutsParameters(content, importedPrivateLayout, importedPublicLayout);

    content = replaceLinksToLayoutsParameters(content, _stagingPrivateLayout, _stagingPublicLayout);

    content =
        ExportImportHelperUtil.replaceExportContentReferences(
            _portletDataContextExport, _referrerStagedModel, content, true);

    String importedContent =
        ExportImportHelperUtil.replaceImportContentReferences(
            _portletDataContextImport, _referrerStagedModel, content);

    Assert.assertEquals(expectedContent, importedContent);
  }
  @Test
  public void testExportImportSelectedLayouts() throws Exception {
    Layout layout = LayoutTestUtil.addLayout(group);

    long[] layoutIds = new long[] {layout.getLayoutId()};

    exportImportLayouts(layoutIds, getImportParameterMap());

    Assert.assertEquals(
        layoutIds.length, LayoutLocalServiceUtil.getLayoutsCount(importedGroup, false));

    importedLayout =
        LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
            layout.getUuid(), importedGroup.getGroupId(), false);

    Assert.assertNotNull(importedLayout);
  }
  protected void validateLayouts(
      LayoutSetPrototype importedLayoutSetPrototype,
      LayoutPrototype importedLayoutPrototype,
      Layout layoutSetPrototypeLayout)
      throws Exception {

    validatePrototypedLayouts(LayoutSetPrototype.class, importedLayoutSetPrototype.getGroupId());
    validatePrototypedLayouts(LayoutPrototype.class, importedLayoutPrototype.getGroupId());

    Assert.assertNotNull(layoutSetPrototypeLayout.getLayoutPrototypeUuid());

    Layout importedLayout =
        LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
            layoutSetPrototypeLayout.getUuid(), importedLayoutSetPrototype.getGroupId(), true);

    Assert.assertNotNull(importedLayout);
    Assert.assertEquals(importedLayoutSetPrototype.getGroupId(), importedLayout.getGroupId());
    Assert.assertEquals(importedLayoutPrototype.getUuid(), importedLayout.getLayoutPrototypeUuid());
  }
  public static Layout getSourcePrototypeLayout(Layout layout) {
    if (Validator.isNull(layout.getUuid())) {
      return null;
    }

    try {
      Group group = null;

      if (Validator.isNotNull(layout.getLayoutPrototypeUuid())) {
        LayoutPrototype layoutPrototype =
            LayoutPrototypeLocalServiceUtil.getLayoutPrototypeByUuid(
                layout.getLayoutPrototypeUuid());

        group = layoutPrototype.getGroup();
      } else {
        LayoutSet layoutSet = layout.getLayoutSet();

        if (Validator.isNull(layoutSet.getLayoutSetPrototypeUuid())) {
          return null;
        }

        LayoutSetPrototype layoutSetPrototype =
            LayoutSetPrototypeLocalServiceUtil.getLayoutSetPrototypeByUuid(
                layoutSet.getLayoutSetPrototypeUuid());

        group = layoutSetPrototype.getGroup();
      }

      return LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
          layout.getSourcePrototypeLayoutUuid(), group.getGroupId());
    } catch (Exception e) {
      _log.error(e, e);
    }

    return null;
  }
  protected void importLayout(
      PortletDataContext portletDataContext,
      User user,
      LayoutCache layoutCache,
      List<Layout> previousLayouts,
      List<Layout> newLayouts,
      Map<Long, Layout> newLayoutsMap,
      Set<Long> newLayoutIds,
      String portletsMergeMode,
      String themeId,
      String colorSchemeId,
      String layoutsImportMode,
      boolean privateLayout,
      boolean importPermissions,
      boolean importPublicLayoutPermissions,
      boolean importUserPermissions,
      boolean importThemeSettings,
      Element rootElement,
      Element layoutElement)
      throws Exception {

    long groupId = portletDataContext.getGroupId();

    String layoutUuid = GetterUtil.getString(layoutElement.attributeValue("layout-uuid"));

    long layoutId = GetterUtil.getInteger(layoutElement.attributeValue("layout-id"));

    long oldLayoutId = layoutId;

    boolean deleteLayout = GetterUtil.getBoolean(layoutElement.attributeValue("delete"));

    if (deleteLayout) {
      Layout layout = LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(layoutUuid, groupId);

      if (layout != null) {
        newLayoutsMap.put(oldLayoutId, layout);

        ServiceContext serviceContext = ServiceContextThreadLocal.getServiceContext();

        LayoutLocalServiceUtil.deleteLayout(layout, false, serviceContext);
      }

      return;
    }

    String path = layoutElement.attributeValue("path");

    if (!portletDataContext.isPathNotProcessed(path)) {
      return;
    }

    Layout layout = (Layout) portletDataContext.getZipEntryAsObject(path);

    Layout existingLayout = null;
    Layout importedLayout = null;

    String friendlyURL = layout.getFriendlyURL();

    if (layoutsImportMode.equals(PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE_ADD_AS_NEW)) {

      layoutId = LayoutLocalServiceUtil.getNextLayoutId(groupId, privateLayout);
      friendlyURL = StringPool.SLASH + layoutId;
    } else if (layoutsImportMode.equals(
        PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE_MERGE_BY_LAYOUT_NAME)) {

      Locale locale = LocaleUtil.getDefault();

      String localizedName = layout.getName(locale);

      for (Layout curLayout : previousLayouts) {
        if (localizedName.equals(curLayout.getName(locale))
            || friendlyURL.equals(curLayout.getFriendlyURL())) {

          existingLayout = curLayout;

          break;
        }
      }

      if (existingLayout == null) {
        layoutId = LayoutLocalServiceUtil.getNextLayoutId(groupId, privateLayout);
      }
    } else if (layoutsImportMode.equals(
        PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE)) {

      existingLayout = LayoutUtil.fetchByG_P_SPLU(groupId, privateLayout, layout.getUuid());

      if (SitesUtil.isLayoutModifiedSinceLastMerge(existingLayout)) {
        newLayoutsMap.put(oldLayoutId, existingLayout);

        return;
      }
    } else {

      // The default behaviour of import mode is
      // PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE_MERGE_BY_LAYOUT_UUID

      existingLayout = LayoutUtil.fetchByUUID_G(layout.getUuid(), groupId);

      if (existingLayout == null) {
        existingLayout = LayoutUtil.fetchByG_P_F(groupId, privateLayout, friendlyURL);
      }

      if (existingLayout == null) {
        layoutId = LayoutLocalServiceUtil.getNextLayoutId(groupId, privateLayout);
      }
    }

    if (_log.isDebugEnabled()) {
      if (existingLayout == null) {
        _log.debug(
            "Layout with {groupId="
                + groupId
                + ",privateLayout="
                + privateLayout
                + ",layoutId="
                + layoutId
                + "} does not exist");
      } else {
        _log.debug(
            "Layout with {groupId="
                + groupId
                + ",privateLayout="
                + privateLayout
                + ",layoutId="
                + layoutId
                + "} exists");
      }
    }

    if (existingLayout == null) {
      long plid = CounterLocalServiceUtil.increment();

      importedLayout = LayoutUtil.create(plid);

      if (layoutsImportMode.equals(
          PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE)) {

        importedLayout.setSourcePrototypeLayoutUuid(layout.getUuid());

        layoutId = LayoutLocalServiceUtil.getNextLayoutId(groupId, privateLayout);
      } else {
        importedLayout.setUuid(layout.getUuid());
        importedLayout.setCreateDate(layout.getCreateDate());
        importedLayout.setModifiedDate(layout.getModifiedDate());
        importedLayout.setLayoutPrototypeUuid(layout.getLayoutPrototypeUuid());
        importedLayout.setLayoutPrototypeLinkEnabled(layout.isLayoutPrototypeLinkEnabled());
        importedLayout.setSourcePrototypeLayoutUuid(layout.getSourcePrototypeLayoutUuid());
      }

      importedLayout.setGroupId(groupId);
      importedLayout.setPrivateLayout(privateLayout);
      importedLayout.setLayoutId(layoutId);

      // Resources

      boolean addGroupPermissions = true;

      Group group = importedLayout.getGroup();

      if (privateLayout && group.isUser()) {
        addGroupPermissions = false;
      }

      boolean addGuestPermissions = false;

      if (!privateLayout || layout.isTypeControlPanel()) {
        addGuestPermissions = true;
      }

      ResourceLocalServiceUtil.addResources(
          user.getCompanyId(),
          groupId,
          user.getUserId(),
          Layout.class.getName(),
          importedLayout.getPlid(),
          false,
          addGroupPermissions,
          addGuestPermissions);

      LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(groupId, privateLayout);

      importedLayout.setLayoutSet(layoutSet);
    } else {
      importedLayout = existingLayout;
    }

    newLayoutsMap.put(oldLayoutId, importedLayout);

    long parentLayoutId = layout.getParentLayoutId();

    Node parentLayoutNode =
        rootElement.selectSingleNode("./layouts/layout[@layout-id='" + parentLayoutId + "']");

    String parentLayoutUuid =
        GetterUtil.getString(layoutElement.attributeValue("parent-layout-uuid"));

    if ((parentLayoutId != LayoutConstants.DEFAULT_PARENT_LAYOUT_ID)
        && (parentLayoutNode != null)) {

      importLayout(
          portletDataContext,
          user,
          layoutCache,
          previousLayouts,
          newLayouts,
          newLayoutsMap,
          newLayoutIds,
          portletsMergeMode,
          themeId,
          colorSchemeId,
          layoutsImportMode,
          privateLayout,
          importPermissions,
          importPublicLayoutPermissions,
          importUserPermissions,
          importThemeSettings,
          rootElement,
          (Element) parentLayoutNode);

      Layout parentLayout = newLayoutsMap.get(parentLayoutId);

      parentLayoutId = parentLayout.getLayoutId();
    } else if (Validator.isNotNull(parentLayoutUuid)) {
      Layout parentLayout =
          LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(parentLayoutUuid, groupId);

      parentLayoutId = parentLayout.getLayoutId();
    }

    if (_log.isDebugEnabled()) {
      _log.debug(
          "Importing layout with layout id "
              + layoutId
              + " and parent layout id "
              + parentLayoutId);
    }

    importedLayout.setCompanyId(user.getCompanyId());
    importedLayout.setParentLayoutId(parentLayoutId);
    importedLayout.setName(layout.getName());
    importedLayout.setTitle(layout.getTitle());
    importedLayout.setDescription(layout.getDescription());
    importedLayout.setKeywords(layout.getKeywords());
    importedLayout.setRobots(layout.getRobots());
    importedLayout.setType(layout.getType());

    if (layout.isTypeArticle()) {
      importJournalArticle(portletDataContext, layout, layoutElement);

      importedLayout.setTypeSettings(layout.getTypeSettings());
    } else if (layout.isTypePortlet()
        && Validator.isNotNull(layout.getTypeSettings())
        && !portletsMergeMode.equals(PortletDataHandlerKeys.PORTLETS_MERGE_MODE_REPLACE)) {

      mergePortlets(importedLayout, layout.getTypeSettings(), portletsMergeMode);
    } else if (layout.isTypeLinkToLayout()) {
      UnicodeProperties typeSettingsProperties = layout.getTypeSettingsProperties();

      long linkToLayoutId =
          GetterUtil.getLong(
              typeSettingsProperties.getProperty("linkToLayoutId", StringPool.BLANK));

      if (linkToLayoutId > 0) {
        Node linkedLayoutNode =
            rootElement.selectSingleNode("./layouts/layout[@layout-id='" + linkToLayoutId + "']");

        if (linkedLayoutNode != null) {
          importLayout(
              portletDataContext,
              user,
              layoutCache,
              previousLayouts,
              newLayouts,
              newLayoutsMap,
              newLayoutIds,
              portletsMergeMode,
              themeId,
              colorSchemeId,
              layoutsImportMode,
              privateLayout,
              importPermissions,
              importPublicLayoutPermissions,
              importUserPermissions,
              importThemeSettings,
              rootElement,
              (Element) linkedLayoutNode);

          Layout linkedLayout = newLayoutsMap.get(linkToLayoutId);

          typeSettingsProperties.setProperty(
              "privateLayout", String.valueOf(linkedLayout.getPrivateLayout()));
          typeSettingsProperties.setProperty(
              "linkToLayoutId", String.valueOf(linkedLayout.getLayoutId()));
        } else {
          if (_log.isWarnEnabled()) {
            StringBundler sb = new StringBundler();

            sb.append("Unable to link layout with friendly URL ");
            sb.append(layout.getFriendlyURL());
            sb.append(" and layout id ");
            sb.append(layout.getLayoutId());
            sb.append(" to layout with layout id ");
            sb.append(linkToLayoutId);

            _log.warn(sb.toString());
          }
        }
      }

      importedLayout.setTypeSettings(layout.getTypeSettings());
    } else {
      importedLayout.setTypeSettings(layout.getTypeSettings());
    }

    importedLayout.setHidden(layout.isHidden());
    importedLayout.setFriendlyURL(friendlyURL);

    if (importThemeSettings) {
      importedLayout.setThemeId(layout.getThemeId());
      importedLayout.setColorSchemeId(layout.getColorSchemeId());
    } else {
      importedLayout.setThemeId(StringPool.BLANK);
      importedLayout.setColorSchemeId(StringPool.BLANK);
    }

    importedLayout.setWapThemeId(layout.getWapThemeId());
    importedLayout.setWapColorSchemeId(layout.getWapColorSchemeId());
    importedLayout.setCss(layout.getCss());
    importedLayout.setPriority(layout.getPriority());
    importedLayout.setLayoutPrototypeUuid(layout.getLayoutPrototypeUuid());
    importedLayout.setLayoutPrototypeLinkEnabled(layout.isLayoutPrototypeLinkEnabled());

    StagingUtil.updateLastImportSettings(layoutElement, importedLayout, portletDataContext);

    fixTypeSettings(importedLayout);

    importedLayout.setIconImage(false);

    if (layout.isIconImage()) {
      String iconImagePath = layoutElement.elementText("icon-image-path");

      byte[] iconBytes = portletDataContext.getZipEntryAsByteArray(iconImagePath);

      if ((iconBytes != null) && (iconBytes.length > 0)) {
        importedLayout.setIconImage(true);

        if (importedLayout.getIconImageId() == 0) {
          long iconImageId = CounterLocalServiceUtil.increment();

          importedLayout.setIconImageId(iconImageId);
        }

        ImageLocalServiceUtil.updateImage(importedLayout.getIconImageId(), iconBytes);
      }
    } else {
      ImageLocalServiceUtil.deleteImage(importedLayout.getIconImageId());
    }

    ServiceContext serviceContext =
        portletDataContext.createServiceContext(layoutElement, importedLayout, null);

    importedLayout.setExpandoBridgeAttributes(serviceContext);

    LayoutUtil.update(importedLayout, false);

    portletDataContext.setPlid(importedLayout.getPlid());
    portletDataContext.setOldPlid(layout.getPlid());

    newLayoutIds.add(importedLayout.getLayoutId());

    newLayouts.add(importedLayout);

    // Layout permissions

    if (importPermissions) {
      _permissionImporter.importLayoutPermissions(
          layoutCache,
          portletDataContext.getCompanyId(),
          groupId,
          user.getUserId(),
          importedLayout,
          layoutElement,
          rootElement,
          importUserPermissions);
    }

    if (importPublicLayoutPermissions) {
      String resourceName = Layout.class.getName();
      String resourcePrimKey = String.valueOf(importedLayout.getPlid());

      Role guestRole =
          RoleLocalServiceUtil.getRole(importedLayout.getCompanyId(), RoleConstants.GUEST);

      if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 5) {
        Resource resource =
            layoutCache.getResource(
                importedLayout.getCompanyId(),
                groupId,
                resourceName,
                ResourceConstants.SCOPE_INDIVIDUAL,
                resourcePrimKey,
                false);

        PermissionLocalServiceUtil.setRolePermissions(
            guestRole.getRoleId(), new String[] {ActionKeys.VIEW}, resource.getResourceId());
      } else if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
        ResourcePermissionLocalServiceUtil.setResourcePermissions(
            importedLayout.getCompanyId(),
            resourceName,
            ResourceConstants.SCOPE_INDIVIDUAL,
            resourcePrimKey,
            guestRole.getRoleId(),
            new String[] {ActionKeys.VIEW});
      } else {
        Resource resource =
            layoutCache.getResource(
                importedLayout.getCompanyId(),
                groupId,
                resourceName,
                ResourceConstants.SCOPE_INDIVIDUAL,
                resourcePrimKey,
                false);

        PermissionLocalServiceUtil.setGroupPermissions(
            groupId, new String[] {ActionKeys.VIEW}, resource.getResourceId());
      }
    }

    _portletImporter.importPortletData(
        portletDataContext, PortletKeys.LAYOUT_CONFIGURATION, null, layoutElement);
  }
  protected void exportLayout(
      PortletDataContext portletDataContext,
      Portlet layoutConfigurationPortlet,
      LayoutCache layoutCache,
      List<Portlet> portlets,
      Map<String, Object[]> portletIds,
      boolean exportPermissions,
      boolean exportUserPermissions,
      Layout layout,
      Element layoutsElement)
      throws Exception {

    String path = portletDataContext.getLayoutPath(layout.getLayoutId()) + "/layout.xml";

    if (!portletDataContext.isPathNotProcessed(path)) {
      return;
    }

    LayoutRevision layoutRevision = null;

    if (LayoutStagingUtil.isBranchingLayout(layout)) {
      ServiceContext serviceContext = ServiceContextThreadLocal.getServiceContext();

      long layoutSetBranchId = ParamUtil.getLong(serviceContext, "layoutSetBranchId");

      if (layoutSetBranchId <= 0) {
        return;
      }

      layoutRevision = LayoutRevisionUtil.fetchByL_H_P(layoutSetBranchId, true, layout.getPlid());

      if (layoutRevision == null) {
        return;
      }

      LayoutStagingHandler layoutStagingHandler = LayoutStagingUtil.getLayoutStagingHandler(layout);

      layoutStagingHandler.setLayoutRevision(layoutRevision);
    }

    Element layoutElement = layoutsElement.addElement("layout");

    if (layoutRevision != null) {
      layoutElement.addAttribute(
          "layout-revision-id", String.valueOf(layoutRevision.getLayoutRevisionId()));
      layoutElement.addAttribute(
          "layout-branch-id", String.valueOf(layoutRevision.getLayoutBranchId()));
      layoutElement.addAttribute(
          "layout-branch-name", String.valueOf(layoutRevision.getLayoutBranch().getName()));
    }

    layoutElement.addAttribute("layout-uuid", layout.getUuid());
    layoutElement.addAttribute("layout-id", String.valueOf(layout.getLayoutId()));

    long parentLayoutId = layout.getParentLayoutId();

    if (parentLayoutId != LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
      Layout parentLayout =
          LayoutLocalServiceUtil.getLayout(
              layout.getGroupId(), layout.isPrivateLayout(), parentLayoutId);

      if (parentLayout != null) {
        layoutElement.addAttribute("parent-layout-uuid", parentLayout.getUuid());
      }
    }

    boolean deleteLayout =
        MapUtil.getBoolean(portletDataContext.getParameterMap(), "delete_" + layout.getPlid());

    if (deleteLayout) {
      layoutElement.addAttribute("delete", String.valueOf(true));

      return;
    }

    portletDataContext.setPlid(layout.getPlid());

    if (layout.isIconImage()) {
      Image image = ImageLocalServiceUtil.getImage(layout.getIconImageId());

      if (image != null) {
        String iconPath = getLayoutIconPath(portletDataContext, layout, image);

        layoutElement.addElement("icon-image-path").addText(iconPath);

        portletDataContext.addZipEntry(iconPath, image.getTextObj());
      }
    }

    _portletExporter.exportPortletData(
        portletDataContext, layoutConfigurationPortlet, layout, null, layoutElement);

    // Layout permissions

    if (exportPermissions) {
      _permissionExporter.exportLayoutPermissions(
          portletDataContext,
          layoutCache,
          portletDataContext.getCompanyId(),
          portletDataContext.getScopeGroupId(),
          layout,
          layoutElement,
          exportUserPermissions);
    }

    if (layout.isTypeArticle()) {
      exportJournalArticle(portletDataContext, layout, layoutElement);
    } else if (layout.isTypeLinkToLayout()) {
      UnicodeProperties typeSettingsProperties = layout.getTypeSettingsProperties();

      long linkToLayoutId =
          GetterUtil.getLong(
              typeSettingsProperties.getProperty("linkToLayoutId", StringPool.BLANK));

      if (linkToLayoutId > 0) {
        try {
          Layout linkedToLayout =
              LayoutLocalServiceUtil.getLayout(
                  portletDataContext.getScopeGroupId(), layout.isPrivateLayout(), linkToLayoutId);

          exportLayout(
              portletDataContext,
              layoutConfigurationPortlet,
              layoutCache,
              portlets,
              portletIds,
              exportPermissions,
              exportUserPermissions,
              linkedToLayout,
              layoutsElement);
        } catch (NoSuchLayoutException nsle) {
        }
      }
    } else if (layout.isTypePortlet()) {
      for (Portlet portlet : portlets) {
        if (portlet.isScopeable() && layout.hasScopeGroup()) {
          String key =
              PortletPermissionUtil.getPrimaryKey(layout.getPlid(), portlet.getPortletId());

          portletIds.put(
              key,
              new Object[] {
                portlet.getPortletId(),
                layout.getPlid(),
                layout.getScopeGroup().getGroupId(),
                StringPool.BLANK,
                layout.getUuid()
              });
        }
      }

      LayoutTypePortlet layoutTypePortlet = (LayoutTypePortlet) layout.getLayoutType();

      for (String portletId : layoutTypePortlet.getPortletIds()) {
        javax.portlet.PortletPreferences jxPreferences =
            PortletPreferencesFactoryUtil.getLayoutPortletSetup(layout, portletId);

        String scopeType = GetterUtil.getString(jxPreferences.getValue("lfrScopeType", null));
        String scopeLayoutUuid =
            GetterUtil.getString(jxPreferences.getValue("lfrScopeLayoutUuid", null));

        long scopeGroupId = portletDataContext.getScopeGroupId();

        if (Validator.isNotNull(scopeType)) {
          Group scopeGroup = null;

          if (scopeType.equals("company")) {
            scopeGroup = GroupLocalServiceUtil.getCompanyGroup(layout.getCompanyId());
          } else if (scopeType.equals("layout")) {
            Layout scopeLayout = null;

            scopeLayout =
                LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
                    scopeLayoutUuid, portletDataContext.getGroupId());

            if (scopeLayout == null) {
              continue;
            }

            scopeGroup = scopeLayout.getScopeGroup();
          } else {
            throw new IllegalArgumentException("Scope type " + scopeType + " is invalid");
          }

          if (scopeGroup != null) {
            scopeGroupId = scopeGroup.getGroupId();
          }
        }

        String key = PortletPermissionUtil.getPrimaryKey(layout.getPlid(), portletId);

        portletIds.put(
            key,
            new Object[] {portletId, layout.getPlid(), scopeGroupId, scopeType, scopeLayoutUuid});
      }
    }

    fixTypeSettings(layout);

    layoutElement.addAttribute("path", path);

    portletDataContext.addExpando(layoutElement, path, layout);

    portletDataContext.addZipEntry(path, layout);
  }
  protected void exportLayout(
      PortletDataContext portletDataContext,
      List<Portlet> portlets,
      long[] layoutIds,
      Map<String, Object[]> portletIds,
      Layout layout)
      throws Exception {

    if (!ArrayUtil.contains(layoutIds, layout.getLayoutId())
        && (layoutIds != null)
        && (layoutIds.length > 0)) {

      Element layoutElement = portletDataContext.getExportDataElement(layout);

      layoutElement.addAttribute("action", Constants.SKIP);

      return;
    }

    StagedModelDataHandlerUtil.exportStagedModel(portletDataContext, layout);

    if (!layout.isSupportsEmbeddedPortlets()) {

      // Only portlet type layouts support page scoping

      return;
    }

    if (layout.isTypePortlet()) {
      for (Portlet portlet : portlets) {
        if (portlet.isScopeable() && layout.hasScopeGroup()) {
          String key =
              PortletPermissionUtil.getPrimaryKey(layout.getPlid(), portlet.getPortletId());

          Group scopeGroup = layout.getScopeGroup();

          portletIds.put(
              key,
              new Object[] {
                portlet.getPortletId(),
                layout.getPlid(),
                scopeGroup.getGroupId(),
                StringPool.BLANK,
                layout.getUuid()
              });
        }
      }
    }

    LayoutTypePortlet layoutTypePortlet = (LayoutTypePortlet) layout.getLayoutType();

    // The getAllPortlets method returns all effective nonsystem portlets
    // for any layout type, including embedded portlets, or in the case of
    // panel type layout, selected portlets

    for (Portlet portlet : layoutTypePortlet.getAllPortlets(false)) {
      String portletId = portlet.getPortletId();

      javax.portlet.PortletPreferences jxPortletPreferences =
          PortletPreferencesFactoryUtil.getLayoutPortletSetup(layout, portletId);

      String scopeType = GetterUtil.getString(jxPortletPreferences.getValue("lfrScopeType", null));
      String scopeLayoutUuid =
          GetterUtil.getString(jxPortletPreferences.getValue("lfrScopeLayoutUuid", null));

      long scopeGroupId = portletDataContext.getScopeGroupId();

      if (Validator.isNotNull(scopeType)) {
        Group scopeGroup = null;

        if (scopeType.equals("company")) {
          scopeGroup = GroupLocalServiceUtil.getCompanyGroup(layout.getCompanyId());
        } else if (scopeType.equals("layout")) {
          Layout scopeLayout = null;

          scopeLayout =
              LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
                  scopeLayoutUuid,
                  portletDataContext.getGroupId(),
                  portletDataContext.isPrivateLayout());

          if (scopeLayout == null) {
            continue;
          }

          scopeGroup = scopeLayout.getScopeGroup();
        } else {
          throw new IllegalArgumentException("Scope type " + scopeType + " is invalid");
        }

        if (scopeGroup != null) {
          scopeGroupId = scopeGroup.getGroupId();
        }
      }

      String key = PortletPermissionUtil.getPrimaryKey(layout.getPlid(), portletId);

      portletIds.put(
          key,
          new Object[] {portletId, layout.getPlid(), scopeGroupId, scopeType, scopeLayoutUuid});
    }
  }