@Override
  public URL getURL(String source) throws IOException {
    int pos = source.indexOf(TemplateConstants.SERVLET_SEPARATOR);

    if (pos == -1) {
      return null;
    }

    String servletContextName = source.substring(0, pos);

    if (servletContextName.equals(PortalUtil.getPathContext())) {
      servletContextName = PortalUtil.getServletContextName();
    }

    ServletContext servletContext = ServletContextPool.get(servletContextName);

    if (servletContext == null) {
      _log.error(
          source
              + " is not valid because "
              + servletContextName
              + " does not map to a servlet context");

      return null;
    }

    String name = source.substring(pos + TemplateConstants.SERVLET_SEPARATOR.length());

    if (_log.isDebugEnabled()) {
      _log.debug(
          name
              + " is associated with the servlet context "
              + servletContextName
              + " "
              + servletContext);
    }

    URL url = servletContext.getResource(name);

    if ((url == null) && name.endsWith("/init_custom.vm")) {
      if (_log.isWarnEnabled()) {
        _log.warn("The template " + name + " should be created");
      }

      ServletContext themeClassicServletContext =
          PortalWebResourcesUtil.getServletContext(
              PortalWebResourceConstants.RESOURCE_TYPE_THEME_CLASSIC);

      url = themeClassicServletContext.getResource("/classic/templates/init_custom.vm");
    }

    return url;
  }
  @Override
  public int doEndTag() {
    try {
      SearchContainerRowTag<R> searchContainerRowTag =
          (SearchContainerRowTag<R>) findAncestorWithClass(this, SearchContainerRowTag.class);

      ResultRow resultRow = searchContainerRowTag.getRow();

      if (index <= -1) {
        List<SearchEntry> searchEntries = resultRow.getEntries();

        index = searchEntries.size();
      }

      if (resultRow.isRestricted()) {
        _href = null;
      }

      ImageSearchEntry imageSearchEntry = new ImageSearchEntry();

      imageSearchEntry.setAlign(getAlign());
      imageSearchEntry.setColspan(getColspan());
      imageSearchEntry.setCssClass(getCssClass());
      imageSearchEntry.setRequest((HttpServletRequest) pageContext.getRequest());
      imageSearchEntry.setResponse((HttpServletResponse) pageContext.getResponse());
      imageSearchEntry.setToggleRowChecker(isToggleRowChecker());

      ServletContext servletContext = ServletContextPool.get(PortalUtil.getServletContextName());

      imageSearchEntry.setServletContext(servletContext);

      imageSearchEntry.setSrc(_src);
      imageSearchEntry.setValign(getValign());

      resultRow.addSearchEntry(index, imageSearchEntry);

      return EVAL_PAGE;
    } finally {
      index = -1;
      _src = null;

      if (!ServerDetector.isResin()) {
        align = SearchEntry.DEFAULT_ALIGN;
        colspan = SearchEntry.DEFAULT_COLSPAN;
        cssClass = SearchEntry.DEFAULT_CSS_CLASS;
        _href = null;
        name = null;
        _toggleRowChecker = false;
        valign = SearchEntry.DEFAULT_VALIGN;
      }
    }
  }
  public Class<?> getImplClass(String implClassName) throws Exception {
    try {
      ClassLoader classLoader = PortalClassLoaderUtil.getClassLoader();

      return classLoader.loadClass(implClassName);
    } catch (Exception e) {
    }

    for (String servletContextName : ServletContextPool.keySet()) {
      try {
        ServletContext servletContext = ServletContextPool.get(servletContextName);

        ClassLoader classLoader =
            (ClassLoader) servletContext.getAttribute(PortletServlet.PORTLET_CLASS_LOADER);

        return classLoader.loadClass(implClassName);
      } catch (Exception e) {
      }
    }

    return null;
  }
  @Override
  public Object doBeforeClass(Description description) {
    if (_mainServlet == null) {
      final MockServletContext mockServletContext =
          new AutoDeployMockServletContext(new FileSystemResourceLoader());

      PortalLifecycleUtil.register(
          new PortalLifecycle() {

            @Override
            public void portalInit() {
              ModuleFrameworkUtilAdapter.registerContext(mockServletContext);
            }

            @Override
            public void portalDestroy() {}
          });

      ServletContextPool.put(StringPool.BLANK, mockServletContext);

      MockServletConfig mockServletConfig = new MockServletConfig(mockServletContext);

      _mainServlet = new MainServlet();

      try {
        _mainServlet.init(mockServletConfig);
      } catch (ServletException se) {
        throw new RuntimeException("The main servlet could not be initialized");
      }

      ServiceTestUtil.initStaticServices();
    }

    ServiceTestUtil.initServices();

    ServiceTestUtil.initPermissions();

    return null;
  }
  protected void exportTheme(LayoutSet layoutSet, ZipWriter zipWriter) throws Exception {

    Theme theme = layoutSet.getTheme();

    String lookAndFeelXML =
        ContentUtil.get("com/liferay/portal/dependencies/liferay-look-and-feel.xml.tmpl");

    lookAndFeelXML =
        StringUtil.replace(
            lookAndFeelXML,
            new String[] {"[$TEMPLATE_EXTENSION$]", "[$VIRTUAL_PATH$]"},
            new String[] {theme.getTemplateExtension(), theme.getVirtualPath()});

    String servletContextName = theme.getServletContextName();

    ServletContext servletContext = ServletContextPool.get(servletContextName);

    if (servletContext == null) {
      if (_log.isWarnEnabled()) {
        _log.warn("Servlet context not found for theme " + theme.getThemeId());
      }

      return;
    }

    File themeZip = new File(zipWriter.getPath() + "/theme.zip");

    ZipWriter themeZipWriter = ZipWriterFactoryUtil.getZipWriter(themeZip);

    themeZipWriter.addEntry("liferay-look-and-feel.xml", lookAndFeelXML);

    File cssPath = null;
    File imagesPath = null;
    File javaScriptPath = null;
    File templatesPath = null;

    if (!theme.isLoadFromServletContext()) {
      ThemeLoader themeLoader = ThemeLoaderFactory.getThemeLoader(servletContextName);

      if (themeLoader == null) {
        _log.error(servletContextName + " does not map to a theme loader");
      } else {
        String realPath =
            themeLoader.getFileStorage().getPath() + StringPool.SLASH + theme.getName();

        cssPath = new File(realPath + "/css");
        imagesPath = new File(realPath + "/images");
        javaScriptPath = new File(realPath + "/javascript");
        templatesPath = new File(realPath + "/templates");
      }
    } else {
      cssPath = new File(servletContext.getRealPath(theme.getCssPath()));
      imagesPath = new File(servletContext.getRealPath(theme.getImagesPath()));
      javaScriptPath = new File(servletContext.getRealPath(theme.getJavaScriptPath()));
      templatesPath = new File(servletContext.getRealPath(theme.getTemplatesPath()));
    }

    exportThemeFiles("css", cssPath, themeZipWriter);
    exportThemeFiles("images", imagesPath, themeZipWriter);
    exportThemeFiles("javascript", javaScriptPath, themeZipWriter);
    exportThemeFiles("templates", templatesPath, themeZipWriter);
  }
    public HotDeployPortalLifecycle(HotDeployEvent hotDeployEvent) {
      _servletContext = hotDeployEvent.getServletContext();
      _classLoader = hotDeployEvent.getContextClassLoader();

      ServletContextPool.put(_servletContext.getServletContextName(), _servletContext);
    }