class ModuleStateManagerImpl implements ModuleStateManager {

    @Override
    public void saveState(String id, String description, Collection<? extends String> tags, Collection<? extends String> modules,
            Node parentNode)
    {
        Document doc = parentNode instanceof Document ? (Document)parentNode : parentNode.getOwnerDocument();
        Element stateElement = (Element)parentNode.appendChild(StateXML.createElement(doc, ModuleStateController.STATE_NAME));
        stateElement.setAttribute("source", getSource());

        stateElement.appendChild(doc.createElement("title")).setTextContent(id);

        if (!StringUtils.isBlank(description))
        {
            stateElement.appendChild(doc.createElement("description")).setTextContent(description);
        }
        if (CollectionUtilities.hasContent(tags))
        {
            try
            {
                XMLUtilities.marshalJAXBObjectToElement(new TagList(tags), stateElement);
            }
            catch (JAXBException e)
            {
                LOGGER.error("Failed to marshal tags to state: " + e, e);
            }
        }

        Collection<ModuleStateController> controllers = getControllers(modules);
        if (!controllers.isEmpty())
        {
            for (ModuleStateController controller : controllers)
            {
                try
                {
                    controller.saveState(stateElement);
                }
                catch (RuntimeException e)
                {
                    LOGGER.error("Error while saving states: " + e, e);
                }
            }
        }
    }

    public  ModuleStateManagerImpl(PreferencesRegistry preferencesRegistry);

}