class TabsTag extends BodyTagSupport {

    private String bean;
    private String css;
    private String currentcss;
    private Boolean justlinks = false;

    /**
     * The name of the request attribute which holds a {@link AdminPageBean} instance.
     * @return the name of the bean
     */
    public String getBean() {
        return bean;
    }

    /**
     * Sets the name of the request attribute to hold a {@link AdminPageBean} instance.
     * @param bean the name of the bean
     */
    public void setBean(String bean) {
        this.bean = bean;
    }

    /**
     * Returns the value of the CSS class to be used for tab decoration. If not set will return a blank string.
     * @return the CSS
     */
    public String getCss() {
        return clean(css);
    }

    /**
     * Sets the CSS used for tab decoration.
     * @param css the CSS
     */
    public void setCss(String css) {
        this.css = css;
    }

    /**
     * Returns the value of the CSS class to be used for the currently selected LI (tab). If not set will
     * return a blank string.
     * @return the CSS class
     */
    public String getCurrentcss() {
        return clean(currentcss);
    }

    /**
     * Sets the CSS class value for the currently selected tab.
     * @param currentcss the CSS class
     */
    public void setCurrentcss(String currentcss) {
        this.currentcss = currentcss;
    }

    /**
     * Returns whether we are in just links mode.
     * @return {@code true} if just displaying links, otherwise {@code false}
     */
    public Boolean getJustlinks() {
        return justlinks;
    }

    /**
     * Sets whether we are just to display links, no list.
     * @param justlinks {@code true} to just display links, otherwise {@code false}
     */
    public void setJustlinks(Boolean justlinks) {
        this.justlinks = justlinks;
    }

    /**
     * Does nothing, returns {@link #EVAL_BODY_BUFFERED} always.
     */
    @Override
    public int doStartTag() throws JspException {
        return EVAL_BODY_BUFFERED;
    }

    /**
     * Gets the {@link AdminPageBean} instance from the request. If it doesn't exist then execution is stopped
     * and nothing is printed. If it exists, retrieve values from it and render the tabs. The body content
     * of the tag is assumed to have an A tag in it with tokens to replace (see class description).
     *
     * @return {@link #EVAL_PAGE} after rendering the tabs.
     * @throws JspException if an exception occurs while rendering the tabs.
     */
    @Override
    public int doEndTag() throws JspException {<FILL_FUNCTION_BODY>}

    /**
     * Cleans the given string - if it's null, it's converted to a blank string. If it has ' then those are
     * converted to double ' so HTML isn't screwed up.
     *
     * @param in the string to clean
     * @return a cleaned version - not null and with escaped characters.
     */
    private String clean(String in) {
        return (in == null ? "" : in.replaceAll("'", "\\'"));
    }
}

        HttpServletRequest request = (HttpServletRequest)pageContext.getRequest();
        // Get the page data bean from the request:
        // If the page info bean is not in the request then no tab will be selected - so, it'll fail gracefully
        String pageID = (String)request.getAttribute("pageID");
        String subPageID = (String)request.getAttribute("subPageID");

        if (pageID == null) {
            Element subPage = AdminConsole.getElemnetByID(subPageID);
            if (subPage != null) {
                pageID = subPage.getParent().getParent().attributeValue("id");
            }
        }
        
        // Get tabs from the model:
        List tabs = AdminConsole.getModel().selectNodes("//tab");
        if (tabs.size() > 0) {
            JspWriter out = pageContext.getOut();
            // Build up the output in a buffer (is probably faster than a bunch of out.write's)
            StringBuilder buf = new StringBuilder();
            if (!justlinks) { buf.append("<ul>"); }
            String body = getBodyContent().getString();
            // For each tab, print out an <LI>.
            Element currentTab = null;
            if (pageID != null) {
                currentTab = (Element)AdminConsole.getModel().selectSingleNode(
                            "//*[@id='" + pageID + "']/ancestor::tab");
            }
            for (int i=0; i<tabs.size(); i++) {
                Element tab = (Element)tabs.get(i);
                String value = body;
                if (value != null) {
                    // The URL for the tab should be the URL of the first item in the tab.
                    String pluginName = tab.attributeValue("plugin");
                    value = value.replaceAll("\\[id]", clean(tab.attributeValue("id")));
                    value = value.replaceAll("\\[url]",request.getContextPath() + "/" + clean(tab.attributeValue("url")));
                    value = value.replaceAll("\\[name]", clean(AdminConsole.getAdminText(tab.attributeValue("name"), pluginName)));
                    value = value.replaceAll("\\[description]", clean(AdminConsole.getAdminText(tab.attributeValue("description"), pluginName)));
                }
                String css = getCss();
                if (tab.equals(currentTab)) {
                    css = getCurrentcss();
                }
                if (!justlinks) { buf.append("<li class=\"").append(css).append("\">"); }
                if (justlinks && i > 0) { buf.append(" | "); }
                buf.append(value);
                if (!justlinks) { buf.append("</li>"); }
            }

            if (!justlinks) { buf.append("</ul>"); }
            try {
                out.write(buf.toString());
            }
            catch (IOException ioe) {
                throw new JspException(ioe.getMessage());
            }
        }
        return EVAL_PAGE;
    
<no_super_class>