- extract interfaces

git-svn-id: https://svn.apache.org/repos/asf/lenya/trunk@1038616 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/org.apache.lenya.core.document.impl/pom.xml b/org.apache.lenya.core.document.impl/pom.xml
index f47d283..815f03d 100644
--- a/org.apache.lenya.core.document.impl/pom.xml
+++ b/org.apache.lenya.core.document.impl/pom.xml
@@ -16,6 +16,11 @@
   <description>This module implements Documents in Lenya</description>
   
   <dependencies>
+  <dependency>
+      <groupId>org.apache.lenya</groupId>
+      <artifactId>lenya-core-document-api</artifactId>
+    </dependency>
+
   <!-- <dependency> -->
   <!--     <groupId>org.apache.lenya</groupId> -->
   <!--     <artifactId>lenya-core-api</artifactId> -->
diff --git a/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DefaultDocumentBuilder.java b/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DefaultDocumentBuilder.java
deleted file mode 100644
index bd3ad6e..0000000
--- a/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DefaultDocumentBuilder.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- */
-
-package org.apache.lenya.cms.publication;
-
-import java.net.MalformedURLException;
-
-import org.apache.avalon.framework.service.ServiceManager;
-import org.apache.avalon.framework.service.Serviceable;
-import org.apache.avalon.framework.thread.ThreadSafe;
-import org.apache.cocoon.util.AbstractLogEnabled;
-import org.apache.lenya.cms.site.SiteNode;
-
-/**
- * Default document builder implementation.
- * 
- * @version $Id$
- */
-public class DefaultDocumentBuilder extends AbstractLogEnabled implements DocumentBuilder,
-        Serviceable, ThreadSafe {
-
-    /**
-     * Ctor.
-     */
-    public DefaultDocumentBuilder() {
-    }
-
-    /**
-     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
-     */
-    public void service(ServiceManager manager) {
-        this.manager = manager;
-    }
-
-    protected ServiceManager manager;
-
-    /**
-     * Removes all "."-separated extensions from a URL (e.g.,
-     * <code>/foo.print.html</code> is transformed to <code>/foo</code>).
-     * @param url The URL to trim.
-     * @return A URL string.
-     */
-    protected String removeExtensions(String url) {
-        int dotIndex = url.indexOf(".");
-        if (dotIndex > -1) {
-            url = url.substring(0, dotIndex);
-        }
-        return url;
-    }
-
-    /**
-     * Returns the language of a URL.
-     * @param urlWithoutSuffix The URL without the suffix.
-     * @return A string.
-     */
-    protected String getLanguage(String urlWithoutSuffix) {
-
-        String language = "";
-        String url = urlWithoutSuffix;
-
-        int languageSeparatorIndex = url.lastIndexOf("_");
-        if (languageSeparatorIndex > -1) {
-            String suffix = url.substring(languageSeparatorIndex + 1);
-            if (suffix.length() <= 5) {
-                language = suffix;
-            }
-        }
-        return language;
-    }
-
-    /**
-     * Returns the extension of a URL.
-     * @param url The URL.
-     * @return The extension.
-     */
-    protected String getExtension(String url) {
-        int startOfSuffix = url.lastIndexOf('.');
-        String suffix = "";
-
-        if ((startOfSuffix > -1) && !url.endsWith(".")) {
-            suffix = url.substring(startOfSuffix + 1);
-        }
-
-        return suffix;
-    }
-
-    public boolean isDocument(Session session, String url) {
-        try {
-            DocumentLocator locator = getLocatorWithoutCheck(session, url);
-            if (locator != null) {
-                Publication pub = session.getPublication(locator.getPublicationId());
-                String path = locator.getPath();
-                Area area = pub.getArea(locator.getArea());
-                if (area.getSite().contains(path)) {
-                    SiteNode node = area.getSite().getNode(path);
-                    if (node.hasLink(locator.getLanguage())) {
-                        return true;
-                    }
-                }
-            }
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-
-        return false;
-    }
-
-    /**
-     * Builds the canonical document URL.
-     * @param session The document factory.
-     * @param locator The document locator.
-     * @return A string.
-     */
-    protected String buildCanonicalDocumentUrl(Session session, DocumentLocator locator) {
-
-        String languageSuffix = "";
-        String language = locator.getLanguage();
-
-        Publication pub = session.getPublication(locator.getPublicationId());
-
-        if (!language.equals(pub.getDefaultLanguage())) {
-            languageSuffix = "_" + language;
-        }
-
-        return locator.getPath() + languageSuffix + ".html";
-    }
-
-    public String buildCanonicalUrl(Session session, DocumentLocator doc) {
-
-        String documentUrl = buildCanonicalDocumentUrl(session, doc);
-        String url = "/" + doc.getPublicationId() + "/" + doc.getArea() + documentUrl;
-        return url;
-    }
-
-    public DocumentLocator getLocator(Session session, String webappUrl) throws MalformedURLException {
-
-        DocumentLocator locator = getLocatorWithoutCheck(session, webappUrl);
-        if (locator == null) {
-            throw new ResourceNotFoundException("The webapp URL [" + webappUrl
-                    + "] does not refer to a document!");
-        }
-        return locator;
-    }
-
-    /**
-     * Creates a document locator for a webapp URL without checking if the
-     * webapp URL refers to a locator first.
-     * @param session The document factory.
-     * @param webappUrl The webapp URL.
-     * @return A document locator or <code>null</code> if the URL doesn't
-     *         refer to a locator.
-     * @throws MalformedURLException if the URL is not a webapp URL. 
-     */
-    protected DocumentLocator getLocatorWithoutCheck(Session session, String webappUrl) throws MalformedURLException {
-
-        if (!webappUrl.startsWith("/")) {
-            return null;
-        }
-        if (webappUrl.substring(1).split("/").length < 3) {
-            return null;
-        }
-
-        URLInformation info = new URLInformation(webappUrl);
-
-        Publication publication = session.getPublication(info.getPublicationId());
-        String documentURL = info.getDocumentUrl();
-        documentURL = removeExtensions(documentURL);
-
-        String language = getLanguage(documentURL);
-        String fullLanguage = "".equals(language) ? "" : ("_" + language);
-        documentURL = documentURL.substring(0, documentURL.length() - fullLanguage.length());
-
-        if ("".equals(language)) {
-            language = publication.getDefaultLanguage();
-        }
-
-        String path = documentURL;
-
-        if (!path.startsWith("/")) {
-            throw new MalformedURLException("Path [" + path + "] does not start with '/'!");
-        }
-
-        return DocumentLocator.getLocator(publication.getId(), info.getArea(), path, language);
-    }
-
-    /**
-     * @see org.apache.lenya.cms.publication.DocumentBuilder#isValidDocumentName(java.lang.String)
-     */
-    public boolean isValidDocumentName(String documentName) {
-        return documentName.matches("[a-zA-Z0-9\\-]+");
-    }
-
-}
diff --git a/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/Document.java b/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/Document.java
deleted file mode 100644
index 02712b7..0000000
--- a/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/Document.java
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- */
-
-package org.apache.lenya.cms.publication;
-
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Date;
-
-import org.apache.lenya.cms.metadata.MetaDataOwner;
-import org.apache.lenya.cms.publication.util.DocumentVisitor;
-import org.apache.lenya.cms.site.Link;
-
-/**
- * A CMS document.
- */
-public interface Document extends Node, MetaDataOwner {
-    
-    /**
-     * The document namespace URI.
-     */
-    String NAMESPACE = "http://apache.org/cocoon/lenya/document/1.0";
-    
-    /**
-     * The default namespace prefix.
-     */
-    String DEFAULT_PREFIX = "lenya";
-    
-    /**
-     * The transactionable type for document objects.
-     */
-    String TRANSACTIONABLE_TYPE = "document";
-    
-    /**
-     * <code>DOCUMENT_META_SUFFIX</code> The suffix for document meta Uris
-     */
-    final String DOCUMENT_META_SUFFIX = ".meta";
-    
-    /**
-     * Returns the date at which point the requested document is considered expired
-     * @return a string in RFC 1123 date format
-     * @throws DocumentException if an error occurs.
-     */
-    Date getExpires() throws DocumentException;
-
-    /**
-     * Returns the document name of this document.
-     * @return the document-name of this document.
-     */
-    String getName();
-    
-    /**
-     * Returns the publication this document belongs to.
-     * @return A publication object.
-     */
-    Publication getPublication();
-    
-    /**
-     * Returns the canonical web application URL.
-     * @return A string.
-     */
-    String getCanonicalWebappURL();
-
-    /**
-     * Returns the canonical document URL.
-     * @return A string.
-     */
-    String getCanonicalDocumentURL();
-
-    /**
-     * Returns the language of this document.
-     * Each document has one language associated to it. 
-     * @return A string denoting the language.
-     */
-    String getLanguage();
-
-    /**
-     * Returns all the languages this document is available in.
-     * A document has one associated language (@see Document#getLanguage)
-     * but there are possibly a number of other languages for which a 
-     * document with the same document-uuid is also available in. 
-     * 
-     * @return An array of strings denoting the languages.
-     */
-    String[] getLanguages();
-
-    /**
-     * Returns the date of the last modification of this document.
-     * @return A date denoting the date of the last modification.
-     * @throws DocumentException if an error occurs.
-     */
-    long getLastModified() throws DocumentException;
-
-    /**
-     * Returns the area this document belongs to.
-     * @return The area.
-     */
-    String getArea();
-
-    /**
-     * Returns the extension in the URL without the dot.
-     * @return A string.
-     */
-    String getExtension();
-
-    /**
-     * Returns the UUID.
-     * @return A string.
-     */
-    String getUUID();
-    
-    /**
-     * Check if a document with the given document-uuid, language and in the given
-     * area actually exists.
-     * 
-     * @return true if the document exists, false otherwise
-     */
-    boolean exists();
-    
-    /**
-     * Check if a document exists with the given document-uuid and the given area
-     * independently of the given language.
-     * 
-     * @return true if a document with the given document-uuid and area exists, false otherwise
-     */
-    boolean existsInAnyLanguage();
-    
-    /**
-     * Returns the URI to resolve the document's source.
-     * The source can only be used for read-only access.
-     * For write access, use {@link #getOutputStream()}.
-     * @return A string.
-     */
-    String getSourceURI();
-    
-    /**
-     * @return The output stream to write the document content to.
-     */
-    OutputStream getOutputStream();
-    
-    /**
-     * Accepts a document visitor.
-     * @param visitor The visitor.
-     * @throws Exception if an error occurs.
-     */
-    void accept(DocumentVisitor visitor) throws Exception;
-
-    /**
-     * Deletes the document.
-     * @throws DocumentException if an error occurs.
-     */
-    void delete() throws DocumentException;
-    
-    /**
-     * @return The resource type of this document (formerly known as doctype)
-     * @throws DocumentException if the resource type has not been set.
-     */
-    ResourceType getResourceType() throws DocumentException;
-    
-    /**
-     * @param resourceType The resource type of this document.
-     */
-    void setResourceType(ResourceType resourceType);
-    
-    /**
-     * @return The source extension used by this document, without the dot.
-     */
-    String getSourceExtension();
-    
-    /**
-     * @param extension The source extension used by this document, without the dot.
-     */
-    void setSourceExtension(String extension);
-    
-    /**
-     * Sets the mime type of this document.
-     * @param mimeType The mime type.
-     */
-    void setMimeType(String mimeType);
-    
-    /**
-     * @return The mime type of this document.
-     * @throws DocumentException if the mime type has not been set.
-     */
-    String getMimeType() throws DocumentException;
-    
-    /**
-     * @return The content length of the document.
-     */
-    long getContentLength();
-    
-    /**
-     * @return The document identifier for this document.
-     */
-    DocumentIdentifier getIdentifier();
-    
-    /**
-     * This is a shortcut to getLink().getNode().getPath().
-     * @return The path of this document in the site structure.
-     * @throws DocumentException if the document is not linked in the site structure.
-     */
-    String getPath() throws DocumentException;
-
-    /**
-     * Checks if a certain translation (language version) of this document exists.
-     * @param language The language.
-     * @return A boolean value.
-     */
-    boolean existsTranslation(String language);
-    
-    /**
-     * Returns a certain translation (language version) of this document.
-     * @param language The language.
-     * @return A document.
-     * @throws ResourceNotFoundException if the language version doesn't exist.
-     */
-    Document getTranslation(String language) throws ResourceNotFoundException;
-    
-    /**
-     * Checks if this document exists in a certain area.
-     * @param area The area.
-     * @return A boolean value.
-     */
-    boolean existsAreaVersion(String area);
-    
-    /**
-     * Returns the document in a certain area.
-     * @param area The area.
-     * @return A document.
-     * @throws ResourceNotFoundException if the area version doesn't exist.
-     */
-    Document getAreaVersion(String area) throws ResourceNotFoundException;
-
-    /**
-     * Checks if a translation of this document exists in a certain area.
-     * @param area The area.
-     * @param language The language.
-     * @return A boolean value.
-     */
-    boolean existsVersion(String area, String language);
-    
-    /**
-     * Returns a translation of this document in a certain area.
-     * @param area The area.
-     * @param language The language.
-     * @return A document.
-     * @throws ResourceNotFoundException if the area version doesn't exist.
-     */
-    Document getVersion(String area, String language) throws ResourceNotFoundException;
-    
-    /**
-     * @return A document locator.
-     */
-    DocumentLocator getLocator();
-    
-    /**
-     * @return The link to this document in the site structure.
-     * @throws DocumentException if the document is not referenced in the site structure.
-     */
-    Link getLink() throws DocumentException;
-    
-    /**
-     * @return The area the document belongs to.
-     */
-    Area area();
-
-    /**
-     * @return if the document is linked in the site structure.
-     */
-    boolean hasLink();
-
-    /**
-     * @return The input stream to obtain the document's content.
-     */
-    InputStream getInputStream();
-    
-    /**
-     * @param i The revision number.
-     * @return A revision.
-     * @throws RepositoryException if the revision doesn't exist.
-     */
-    Document getRevision(int i) throws RepositoryException;
-
-    /**
-     * @return The revision number of this document.
-     */
-    int getRevisionNumber();
-    
-    History getHistory();
-
-}
diff --git a/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentBuildException.java b/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentBuildException.java
deleted file mode 100644
index 59ebdb8..0000000
--- a/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentBuildException.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- */
-
-package org.apache.lenya.cms.publication;
-
-/**
- * Document build exception.
- *
- * @version $Id$
- */
-public class DocumentBuildException extends PublicationException {
-    /**
-	 * 
-	 */
-	private static final long serialVersionUID = 1L;
-
-	/**
-     * Constructor.
-     */
-    public DocumentBuildException() {
-        super();
-    }
-
-    /**
-     * Constructor.
-     * @param message A message.
-     */
-    public DocumentBuildException(String message) {
-        super(message);
-    }
-
-    /**
-     * Constructor.
-     * @param cause The cause of the exception.
-     */
-    public DocumentBuildException(Throwable cause) {
-        super(cause);
-    }
-
-    /**
-     * Constructor.
-     * @param message A message.
-     * @param cause The cause of the exception.
-     */
-    public DocumentBuildException(String message, Throwable cause) {
-        super(message, cause);
-    }
-}
diff --git a/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentBuilder.java b/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentBuilder.java
deleted file mode 100644
index 7a99efa..0000000
--- a/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentBuilder.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- */
-
-/* $Id$  */
-
-package org.apache.lenya.cms.publication;
-
-import java.net.MalformedURLException;
-
-/**
- * A document builder builds a document from a URL.
- */
-public interface DocumentBuilder {
-
-    /**
-     * The Avalon role.
-     */
-    String ROLE = DocumentBuilder.class.getName();
-    
-    /**
-     * Returns a document for a web application URL.
-     * @param factory The factory.
-     * @param webappUrl The web application URL.
-     * @return A document identifier.
-     * @throws MalformedURLException if the URL is not a webapp URL. 
-     */
-    DocumentLocator getLocator(Session session, String webappUrl) throws MalformedURLException;
-
-    /**
-     * Checks if an URL corresponds to a CMS document.
-     * @param factory The document factory.
-     * @param url The URL of the form /{publication-id}/...
-     * @return A boolean value.
-     * @throws DocumentBuildException when something went wrong.
-     */
-    boolean isDocument(Session session, String url);
-
-    /**
-     * Builds an URL corresponding to a CMS document.
-     * @param factory The document factory.
-     * @param locator The locator.
-     * @return a String The corresponding URL.
-     */
-    String buildCanonicalUrl(Session session, DocumentLocator locator);
-
-    /**
-     * Checks if a document name is valid.
-     * @param documentName The document name.
-     * @return A boolean value.
-     */
-    boolean isValidDocumentName(String documentName);
-
-}
\ No newline at end of file
diff --git a/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentDoesNotExistException.java b/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentDoesNotExistException.java
deleted file mode 100644
index 7f4f15c..0000000
--- a/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentDoesNotExistException.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- */
-
-/* $Id$  */
-
-package org.apache.lenya.cms.publication;
-
-/**
- * Document does not exist exception
- */
-public class DocumentDoesNotExistException extends DocumentException {
-
-    /**
-	 * 
-	 */
-	private static final long serialVersionUID = 1L;
-
-	/**
-     * Creates a new DocumentDoesNotExistException
-     * 
-     */
-    public DocumentDoesNotExistException() {
-        super();
-    }
-
-    /**
-     * Creates a new DocumentDoesNotExistException
-     * @param message the exception message
-     */
-    public DocumentDoesNotExistException(String message) {
-        super(message);
-    }
-
-    /**
-     * Creates a new DocumentDoesNotExistException
-     * @param message the exception message
-     * @param cause the cause of the exception
-     */
-    public DocumentDoesNotExistException(String message, Throwable cause) {
-        super(message, cause);
-    }
-
-    /**
-     * Creates a new DocumentDoesNotExistException
-     * @param cause the cause of the exception
-     */
-    public DocumentDoesNotExistException(Throwable cause) {
-        super(cause);
-    }
-
-}
diff --git a/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentException.java b/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentException.java
deleted file mode 100644
index 35ab77d..0000000
--- a/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentException.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- */
-
-/* $Id$  */
-
-package org.apache.lenya.cms.publication;
-
-/**
- * Document exception
- */
-public class DocumentException extends PublicationException {
-
-    /**
-	 * 
-	 */
-	private static final long serialVersionUID = 1L;
-
-	/**
-     * Creates a new DocumentException
-     * 
-     */
-    public DocumentException() {
-        super();
-    }
-
-    /**
-     * Creates a new DocumentException
-     * 
-     * @param message the exception message
-     */
-    public DocumentException(String message) {
-        super(message);
-    }
-
-    /**
-     * Creates a new DocumentException
-     * 
-     * @param message the exception message
-     * @param cause the cause of the exception
-     */
-    public DocumentException(String message, Throwable cause) {
-        super(message, cause);
-    }
-
-    /**
-     * Creates a new DocumentException
-     * 
-     * @param cause the cause of the exception
-     */
-    public DocumentException(Throwable cause) {
-        super(cause);
-    }
-
-}
diff --git a/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentFactory.java b/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentFactory.java
deleted file mode 100644
index 048b8ae..0000000
--- a/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentFactory.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- */
-package org.apache.lenya.cms.publication;
-
-/**
- * A DocumentIdentityMap avoids the multiple instanciation of a document object.
- * 
- * @version $Id$
- */
-public interface DocumentFactory {
-
-    /**
-     * Returns a document.
-     * @param identifier The identifier of the document.
-     * @return A document.
-     * @throws ResourceNotFoundException if the document does not exist.
-     */
-    Document get(DocumentIdentifier identifier) throws ResourceNotFoundException;
-    
-    /**
-     * Returns a document.
-     * @param publication The publication.
-     * @param area The area.
-     * @param uuid The document ID.
-     * @param language The language.
-     * @return A document.
-     * @throws ResourceNotFoundException if the document does not exist.
-     */
-    Document get(Publication publication, String area, String uuid, String language)
-            throws ResourceNotFoundException;
-
-    /**
-     * Returns a revision of a document.
-     * @param publication The publication.
-     * @param area The area.
-     * @param uuid The document ID.
-     * @param language The language.
-     * @param revision The revision..
-     * @return A document.
-     * @throws ResourceNotFoundException if the document does not exist.
-     */
-    Document get(Publication publication, String area, String uuid, String language, int revision)
-            throws ResourceNotFoundException;
-
-    /**
-     * Returns the document identified by a certain web application URL.
-     * @param webappUrl The web application URL.
-     * @return A document.
-     * @throws ResourceNotFoundException if an error occurs.
-     */
-    Document getFromURL(String webappUrl) throws ResourceNotFoundException;
-
-    /**
-     * Builds a document for the default language.
-     * @param publication The publication.
-     * @param area The area.
-     * @param uuid The document UUID.
-     * @return A document.
-     * @throws ResourceNotFoundException if an error occurs.
-     */
-    Document get(Publication publication, String area, String uuid)
-            throws ResourceNotFoundException;
-
-    /**
-     * Checks if a webapp URL represents a document.
-     * @param webappUrl A web application URL.
-     * @return A boolean value.
-     */
-    boolean isDocument(String webappUrl);
-    
-    /**
-     * @return The session.
-     */
-    Session getSession();
-    
-    /**
-     * @param id The publication ID.
-     * @return A publication.
-     * @throws PublicationException if the publication does not exist.
-     */
-    Publication getPublication(String id) throws PublicationException;
-    
-    /**
-     * @return All publication IDs.
-     */
-    String[] getPublicationIds();
-    
-    /**
-     * @param id The publication ID.
-     * @return If a publication with this ID exists.
-     */
-    boolean existsPublication(String id);
-}
diff --git a/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentFactoryBuilder.java b/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentFactoryBuilder.java
deleted file mode 100644
index c0f333c..0000000
--- a/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentFactoryBuilder.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- */
-package org.apache.lenya.cms.publication;
-
-/**
- * Document factory builder.
- */
-public interface DocumentFactoryBuilder {
-
-    /**
-     * Creates a new document factory.
-     * @param session The session.
-     * @return A document identity map.
-     */
-    DocumentFactory createDocumentFactory(Session session);
-
-}
diff --git a/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentFactoryImpl.java b/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentFactoryImpl.java
index 4e557aa..f0d7da4 100644
--- a/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentFactoryImpl.java
+++ b/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentFactoryImpl.java
@@ -123,10 +123,12 @@
      * @return A document.
      * @throws DocumentBuildException if an error occurs.
      */
+  //florent : seems never use, imply cyclic dependencies
+    /*
     public Document getLanguageVersion(Document document, String language)
             throws DocumentBuildException {
         return get(document.getPublication(), document.getArea(), document.getUUID(), language);
-    }
+    }*/
 
     /**
      * Builds a clone of a document for another area.
@@ -135,9 +137,11 @@
      * @return A document.
      * @throws ResourceNotFoundException if an error occurs.
      */
+    //florent : seems never use, imply cyclic dependencies
+    /*
     public Document getAreaVersion(Document document, String area) throws ResourceNotFoundException {
         return get(document.getPublication(), area, document.getUUID(), document.getLanguage());
-    }
+    }*/
 
     /**
      * Builds a document for the default language.
@@ -275,7 +279,7 @@
         try {
             Publication publication = getPublication(publicationId);
             DocumentBuilder builder = publication.getDocumentBuilder();
-            DocumentIdentifier identifier = new DocumentIdentifier(publicationId, area, uuid,
+            DocumentIdentifier identifier = new DocumentIdentifierImpl(publicationId, area, uuid,
                     language);
             document = buildDocument(identifier, revision, builder);
         } catch (Exception e) {
diff --git a/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentIdToPathMapper.java b/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentIdToPathMapper.java
deleted file mode 100644
index 43fee73..0000000
--- a/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentIdToPathMapper.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- */
-
-/* $Id$  */
-
-package org.apache.lenya.cms.publication;
-
-/**
- * Document Id to Path mapper interface
- */
-public interface DocumentIdToPathMapper {
-
-    /**
-     * Compute the document-path for a given publication, area and document-uuid. The file separator
-     * is the slash (/).
-     * 
-     * @param uuid the UUID of the document
-     * @param language the language of the document
-     * 
-     * @return the path to the document, without publication ID and area
-     */
-    String getPath(String uuid, String language);
-
-}
diff --git a/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentIdentifier.java b/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentIdentifierImpl.java
similarity index 90%
rename from org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentIdentifier.java
rename to org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentIdentifierImpl.java
index 38cac3e..109200b 100644
--- a/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentIdentifier.java
+++ b/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentIdentifierImpl.java
@@ -20,7 +20,7 @@
 /**
  * Value object to identify documents.
  */
-public class DocumentIdentifier {
+public class DocumentIdentifierImpl implements DocumentIdentifier {
 
     private String publicationId;
     private String area;
@@ -34,7 +34,7 @@
      * @param uuid The document UUID.
      * @param language The language.
      */
-    public DocumentIdentifier(String pubId, String area, String uuid, String language) {
+    public DocumentIdentifierImpl(String pubId, String area, String uuid, String language) {
 
         if (uuid.startsWith("/") && uuid.split("-").length == 4) {
             throw new IllegalArgumentException("The UUID [" + uuid + "] must not begin with a '/'!");
@@ -79,7 +79,7 @@
     }
 
     public boolean equals(Object obj) {
-        return (obj instanceof DocumentIdentifier) && obj.hashCode() == hashCode();
+        return (obj instanceof DocumentIdentifierImpl) && obj.hashCode() == hashCode();
     }
 
     public int hashCode() {
diff --git a/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentImpl.java b/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentImpl.java
index 282b510..3d9875d 100644
--- a/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentImpl.java
+++ b/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentImpl.java
@@ -172,6 +172,13 @@
         }
         return this.publication;
     }
+    
+    public String getPublicationId(){
+    	if (this.publication == null) {
+        this.publication = getSession().getPublication(getIdentifier().getPublicationId());
+    }
+    return this.publication.getId();
+    }
 
     /**
      * @see org.apache.lenya.cms.publication.Document#getLastModified()
@@ -276,6 +283,8 @@
         }
     }
 
+  //florent : seems never use, imply cyclic dependencies
+    /*
     public boolean existsInAnyLanguage() throws ResourceNotFoundException {
         String[] languages = getLanguages();
 
@@ -302,7 +311,7 @@
             return false;
         }
 
-    }
+    }*/
 
     public DocumentIdentifier getIdentifier() {
         return this.identifier;
@@ -482,6 +491,8 @@
         return getLink().getNode().getPath();
     }
 
+  //florent : seems never use, imply cyclic dependencies
+    /*
     public boolean existsAreaVersion(String area) {
         String sourceUri = getSourceURI(getPublication(), area, getUUID(), getLanguage());
         try {
@@ -489,15 +500,17 @@
         } catch (Exception e) {
             throw new RuntimeException(e);
         }
-    }
+    }*/
 
     public boolean existsTranslation(String language) {
         return area().contains(getUUID(), language);
     }
 
+  //florent : seems never use, imply cyclic dependencies
+    /*
     public Document getAreaVersion(String area) throws ResourceNotFoundException {
         return getPublication().getArea(area).getDocument(getUUID(), getLanguage());
-    }
+    }*/
 
     public Document getTranslation(String language) throws ResourceNotFoundException {
         return area().getDocument(getUUID(), language);
@@ -548,6 +561,8 @@
         return pub.getContentUri(area) + "/" + path;
     }
 
+  //florent : seems never use, imply cyclic dependencies
+    /*
     public boolean existsVersion(String area, String language) {
         String sourceUri = getSourceURI(getPublication(), area, getUUID(), language);
         try {
@@ -555,7 +570,7 @@
         } catch (Exception e) {
             throw new RuntimeException(e);
         }
-    }
+    }*/
 
     public Document getVersion(String area, String language) throws ResourceNotFoundException {
         return getPublication().getArea(area).getDocument(getUUID(), language);
@@ -579,9 +594,11 @@
         return area().getSite().containsByUuid(getUUID(), getLanguage());
     }
 
+  //florent : seems never use, imply cyclic dependencies
+    /*
     public Area area() {
         return getPublication().getArea(getArea());
-    }
+    }*/
 
     public void setResourceType(ResourceType resourceType) {
         Validate.notNull(resourceType);
diff --git a/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentLocator.java b/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentLocatorImpl.java
similarity index 94%
rename from org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentLocator.java
rename to org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentLocatorImpl.java
index c215ddf..5ab00f9 100644
--- a/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentLocator.java
+++ b/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentLocatorImpl.java
@@ -25,7 +25,7 @@
  * A DocumentLocator describes a document based on its path in the site structure. The actual
  * document doesn't have to exist.
  */
-public class DocumentLocator {
+public class DocumentLocatorImpl implements DocumentLocator {
 
     private static Map locators = new WeakHashMap();
 
@@ -41,7 +41,7 @@
         String key = DocumentLocator.getKey(pubId, area, path, language);
         DocumentLocator locator = (DocumentLocator) locators.get(key);
         if (locator == null) {
-            locator = new DocumentLocator(pubId, area, path, language);
+            locator = new DocumentLocatorImpl(pubId, area, path, language);
             locators.put(key, locator);
         }
         return locator;
@@ -56,7 +56,7 @@
     private String path;
     private String language;
 
-    protected DocumentLocator(String pubId, String area, String path, String language) {
+    protected DocumentLocatorImpl(String pubId, String area, String path, String language) {
         this.path = path;
         this.pubId = pubId;
         this.area = area;
@@ -197,6 +197,10 @@
         return DocumentLocator.getLocator(getPublicationId(), area, getPath(), getLanguage());
     }
 
+    /*
+     * florent : seems not used, and introduce a cyclic dependencie with publication
+     */
+    /*
     public Document getDocument(Session session) throws ResourceNotFoundException {
         try {
             Publication pub = session.getPublication(getPublicationId());
@@ -205,6 +209,6 @@
         } catch (PublicationException e) {
             throw new ResourceNotFoundException(e);
         }
-    }
+    }*/
 
 }
diff --git a/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentManager.java b/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentManager.java
deleted file mode 100644
index 77fab08..0000000
--- a/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentManager.java
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- */
-package org.apache.lenya.cms.publication;
-
-import org.apache.lenya.cms.publication.util.DocumentSet;
-
-/**
- * Helper to manage documents. It takes care of attachments etc.
- * 
- * @version $Id$
- */
-public interface DocumentManager {
-
-    /**
-     * The Avalon component role.
-     */
-    String ROLE = DocumentManager.class.getName();
-
-    /**
-     * Copies a document from one location to another location.
-     * @param sourceDocument The document to copy.
-     * @param destination The destination document.
-     * @throws PublicationException if a document which destinationDocument depends on does not
-     *             exist.
-     */
-    void copy(Document sourceDocument, DocumentLocator destination) throws PublicationException;
-
-    /**
-     * Copies a document to another area.
-     * @param sourceDocument The document to copy.
-     * @param destinationArea The destination area.
-     * @throws PublicationException if a document which the destination document depends on does not
-     *             exist.
-     */
-    void copyToArea(Document sourceDocument, String destinationArea) throws PublicationException;
-
-    /**
-     * Copies a document set to another area.
-     * @param documentSet The document set to copy.
-     * @param destinationArea The destination area.
-     * @throws PublicationException if a document which one of the destination documents depends on
-     *             does not exist.
-     */
-    void copyToArea(DocumentSet documentSet, String destinationArea) throws PublicationException;
-
-    /**
-     * Creates a new document in the same publication the <code>parentDocument</code> belongs to
-     * with the given parameters:
-     * 
-     * @param sourceDocument The document to initialize the contents and meta data from.
-     * @param area The target area.
-     * @param path The target path.
-     * @param language The target language.
-     * @param extension The extension to use for the document source.
-     * @param navigationTitle navigation title
-     * @param visibleInNav determines the visibility of a node in the navigation
-     * @return The added document.
-     * 
-     * @throws DocumentBuildException if the document can not be created
-     * @throws PublicationException if the document is already contained.
-     */
-    Document add(Document sourceDocument, String area, String path, String language,
-            String extension, String navigationTitle, boolean visibleInNav)
-            throws DocumentBuildException, PublicationException;
-
-    /**
-     * Creates a new document with the given parameters:
-     * @param resourceType the document type (aka resource type) of the new document
-     * @param contentSourceUri The URI to read the content from.
-     * @param pub The publication.
-     * @param area The area.
-     * @param path The path.
-     * @param language The language.
-     * @param extension The extension to use for the document source, without the leading dot.
-     * @param navigationTitle The navigation title.
-     * @param visibleInNav The navigation visibility.
-     * @return The added document.
-     * 
-     * @throws DocumentBuildException if the document can not be created
-     * @throws PublicationException if the document is already contained.
-     */
-    Document add(ResourceType resourceType, String contentSourceUri,
-            Publication pub, String area, String path, String language, String extension,
-            String navigationTitle, boolean visibleInNav) throws DocumentBuildException,
-            PublicationException;
-
-    /**
-     * Creates a new document without adding it to the site structure.
-     * @param resourceType the document type (aka resource type) of the new document
-     * @param contentSourceUri The URI to read the content from.
-     * @param pub The publication.
-     * @param area The area.
-     * @param language The language.
-     * @param extension The extension to use for the document source, without the leading dot.
-     * @return The added document.
-     * 
-     * @throws DocumentBuildException if the document can not be created
-     * @throws PublicationException if the document is already contained.
-     */
-    Document add(ResourceType resourceType, String contentSourceUri,
-            Publication pub, String area, String language, String extension)
-            throws DocumentBuildException, PublicationException;
-
-    /**
-     * Adds a new version of a document with a different language and / or in a different area.
-     * 
-     * @param sourceDocument The document to initialize the contents and meta data from.
-     * @param area The area.
-     * @param language The language of the new document.
-     * @return The added document.
-     * 
-     * @throws DocumentBuildException if the document can not be created
-     * @throws PublicationException if the document is already contained.
-     */
-    Document addVersion(Document sourceDocument, String area, String language)
-            throws DocumentBuildException, PublicationException;
-
-    /**
-     * Adds a new version of a document with a different language and / or in a different area.
-     * 
-     * @param sourceDocument The document to initialize the contents and meta data from.
-     * @param area The area.
-     * @param language The language of the new document.
-     * @param addToSite If the new version should be added to the site structure.
-     * @return The added document.
-     * 
-     * @throws DocumentBuildException if the document can not be created
-     * @throws PublicationException if the document is already contained.
-     */
-    Document addVersion(Document sourceDocument, String area, String language, boolean addToSite)
-            throws DocumentBuildException, PublicationException;
-
-    /**
-     * Deletes a document from the content repository and from the site structure.
-     * @param document The document to delete.
-     * @throws PublicationException when something went wrong.
-     */
-    void delete(Document document) throws PublicationException;
-
-    /**
-     * Moves a document from one location to another.
-     * @param sourceDocument The source document.
-     * @param destination The destination document.
-     * @throws PublicationException if a document which the destination document depends on does not
-     *             exist.
-     */
-    void move(Document sourceDocument, DocumentLocator destination) throws PublicationException;
-
-    /**
-     * Moves a document set from one location to another. A source is moved to the destination of
-     * the same position in the set.
-     * @param sources The source documents.
-     * @param destinations The destination documents.
-     * @throws PublicationException if a document which the destination document depends on does not
-     *             exist.
-     */
-    void move(DocumentSet sources, DocumentSet destinations) throws PublicationException;
-
-    /**
-     * Copies a document set from one location to another. A source is copied to the destination of
-     * the same position in the set.
-     * @param sources The source documents.
-     * @param destinations The destination documents.
-     * @throws PublicationException if a document which the destination document depends on does not
-     *             exist.
-     */
-    void copy(DocumentSet sources, DocumentSet destinations) throws PublicationException;
-
-    /**
-     * Moves a document to another location, incl. all requiring documents. If a sitetree is used,
-     * this means that the whole subtree is moved.
-     * @param sourceArea The source area.
-     * @param sourcePath The source path.
-     * @param targetArea The target area.
-     * @param targetPath The target path.
-     * @throws PublicationException if an error occurs.
-     */
-    void moveAll(Area sourceArea, String sourcePath, Area targetArea, String targetPath)
-            throws PublicationException;
-
-    /**
-     * Moves all language versions of a document to another location.
-     * @param sourceArea The source area.
-     * @param sourcePath The source path.
-     * @param targetArea The target area.
-     * @param targetPath The target path.
-     * @throws PublicationException if the documents could not be moved.
-     */
-    void moveAllLanguageVersions(Area sourceArea, String sourcePath, Area targetArea,
-            String targetPath) throws PublicationException;
-
-    /**
-     * Copies a document to another location, incl. all requiring documents. If a sitetree is used,
-     * this means that the whole subtree is copied.
-     * @param sourceArea The source area.
-     * @param sourcePath The source path.
-     * @param targetArea The target area.
-     * @param targetPath The target path.
-     * @throws PublicationException if an error occurs.
-     */
-    void copyAll(Area sourceArea, String sourcePath, Area targetArea, String targetPath)
-            throws PublicationException;
-
-    /**
-     * Copies all language versions of a document to another location.
-     * @param sourceArea The source area.
-     * @param sourcePath The source path.
-     * @param targetArea The target area.
-     * @param targetPath The target path.
-     * @throws PublicationException if the documents could not be copied.
-     */
-    void copyAllLanguageVersions(Area sourceArea, String sourcePath, Area targetArea,
-            String targetPath) throws PublicationException;
-
-    /**
-     * Deletes a document, incl. all requiring documents. If a sitetree is used, this means that the
-     * whole subtree is deleted.
-     * @param document The document.
-     * @throws PublicationException if an error occurs.
-     */
-    void deleteAll(Document document) throws PublicationException;
-
-    /**
-     * Deletes all language versions of a document.
-     * @param document The document.
-     * @throws PublicationException if the documents could not be copied.
-     */
-    void deleteAllLanguageVersions(Document document) throws PublicationException;
-
-    /**
-     * Deletes a set of documents.
-     * @param documents The documents.
-     * @throws PublicationException if an error occurs.
-     */
-    void delete(DocumentSet documents) throws PublicationException;
-
-}
\ No newline at end of file
diff --git a/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentManagerImpl.java b/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentManagerImpl.java
deleted file mode 100644
index f49d155..0000000
--- a/org.apache.lenya.core.document.impl/src/main/java/org/apache/lenya/cms/publication/DocumentManagerImpl.java
+++ /dev/null
@@ -1,862 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- */
-package org.apache.lenya.cms.publication;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.cocoon.spring.configurator.WebAppContextUtils;
-import org.apache.cocoon.util.AbstractLogEnabled;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.io.output.ByteArrayOutputStream;
-import org.apache.excalibur.source.Source;
-import org.apache.excalibur.source.SourceResolver;
-import org.apache.lenya.cms.metadata.MetaData;
-import org.apache.lenya.cms.metadata.MetaDataException;
-import org.apache.lenya.cms.publication.util.DocumentSet;
-import org.apache.lenya.cms.publication.util.DocumentVisitor;
-import org.apache.lenya.cms.repository.Node;
-import org.apache.lenya.cms.repository.NodeFactory;
-import org.apache.lenya.cms.repository.UUIDGenerator;
-import org.apache.lenya.cms.site.Link;
-import org.apache.lenya.cms.site.NodeIterator;
-import org.apache.lenya.cms.site.NodeSet;
-import org.apache.lenya.cms.site.SiteException;
-import org.apache.lenya.cms.site.SiteManager;
-import org.apache.lenya.cms.site.SiteNode;
-import org.apache.lenya.cms.site.SiteStructure;
-import org.apache.lenya.cms.site.SiteUtil;
-
-/**
- * DocumentManager implementation.
- * 
- * @version $Id$
- */
-public class DocumentManagerImpl extends AbstractLogEnabled implements DocumentManager {
-
-    private SourceResolver sourceResolver;
-    private UUIDGenerator uuidGenerator;
-    private NodeFactory nodeFactory;
-
-    /**
-     * @see org.apache.lenya.cms.publication.DocumentManager#add(org.apache.lenya.cms.publication.Document,
-     *      java.lang.String, java.lang.String, java.lang.String, java.lang.String,
-     *      java.lang.String, boolean)
-     */
-    public Document add(Document sourceDocument, String area, String path, String language,
-            String extension, String navigationTitle, boolean visibleInNav)
-            throws DocumentBuildException, PublicationException {
-
-        Document document = add(sourceDocument.getResourceType(), sourceDocument.getInputStream(),
-                sourceDocument.getPublication(), area, path, language, extension, navigationTitle,
-                visibleInNav, sourceDocument.getMimeType());
-
-        copyMetaData(sourceDocument, document);
-        return document;
-    }
-
-    /**
-     * Copies meta data from one document to another. If the destination document is a different
-     * area version, the meta data are duplicated (i.e., onCopy = delete is neglected).
-     * @param source
-     * @param destination
-     * @throws PublicationException
-     */
-    protected void copyMetaData(Document source, Document destination) throws PublicationException {
-
-        boolean duplicate = source.getUUID().equals(destination.getUUID())
-                && source.getLanguage().equals(destination.getLanguage())
-                && !source.getArea().equals(destination.getArea());
-
-        try {
-            String[] uris = source.getMetaDataNamespaceUris();
-            for (int i = 0; i < uris.length; i++) {
-                if (duplicate) {
-                    destination.getMetaData(uris[i]).forcedReplaceBy(source.getMetaData(uris[i]));
-                } else {
-                    destination.getMetaData(uris[i]).replaceBy(source.getMetaData(uris[i]));
-                }
-            }
-        } catch (MetaDataException e) {
-            throw new PublicationException(e);
-        }
-    }
-
-    public Document add(ResourceType documentType, String initialContentsURI, Publication pub,
-            String area, String path, String language, String extension, String navigationTitle,
-            boolean visibleInNav) throws DocumentBuildException, DocumentException,
-            PublicationException {
-
-        Area areaObj = pub.getArea(area);
-        SiteStructure site = areaObj.getSite();
-        if (site.contains(path) && site.getNode(path).hasLink(language)) {
-            throw new DocumentException("The link [" + path + ":" + language
-                    + "] is already contained in site [" + site + "]");
-        }
-
-        Document document = add(documentType, initialContentsURI, pub, area, language, extension);
-
-        addToSiteManager(path, document, navigationTitle, visibleInNav);
-        return document;
-    }
-
-    protected Document add(ResourceType documentType, InputStream initialContentsStream,
-            Publication pub, String area, String path, String language, String extension,
-            String navigationTitle, boolean visibleInNav, String mimeType)
-            throws DocumentBuildException, DocumentException, PublicationException {
-
-        Area areaObj = pub.getArea(area);
-        SiteStructure site = areaObj.getSite();
-        if (site.contains(path) && site.getNode(path).hasLink(language)) {
-            throw new DocumentException("The link [" + path + ":" + language
-                    + "] is already contained in site [" + site + "]");
-        }
-
-        Document document = add(documentType, initialContentsStream, pub, area, language,
-                extension, mimeType);
-
-        addToSiteManager(path, document, navigationTitle, visibleInNav);
-        return document;
-    }
-
-    public Document add(ResourceType documentType, String initialContentsURI, Publication pub,
-            String area, String language, String extension) throws DocumentBuildException,
-            DocumentException, PublicationException {
-
-        String uuid = getUuidGenerator().nextUUID();
-        Source source = null;
-        try {
-            source = getSourceResolver().resolveURI(initialContentsURI);
-            return add(documentType, uuid, source.getInputStream(), pub, area, language, extension,
-                    getMimeType(source));
-        } catch (Exception e) {
-            throw new PublicationException(e);
-        } finally {
-            if (source != null) {
-                getSourceResolver().release(source);
-            }
-        }
-    }
-
-    protected String getMimeType(Source source) {
-        String mimeType = source.getMimeType();
-        if (mimeType == null) {
-            mimeType = "";
-        }
-        return mimeType;
-    }
-
-    protected Document add(ResourceType documentType, InputStream initialContentsStream,
-            Publication pub, String area, String language, String extension, String mimeType)
-            throws DocumentBuildException, DocumentException, PublicationException {
-
-        String uuid = getUuidGenerator().nextUUID();
-        return add(documentType, uuid, initialContentsStream, pub, area, language, extension,
-                mimeType);
-    }
-
-    protected Document add(ResourceType documentType, String uuid, InputStream stream,
-            Publication pub, String area, String language, String extension, String mimeType)
-            throws DocumentBuildException {
-        try {
-
-            Area areaObj = pub.getArea(area);
-            if (areaObj.contains(uuid, language)) {
-                throw new DocumentBuildException("The document [" + pub.getId() + ":" + area + ":"
-                        + uuid + ":" + language + "] already exists!");
-            }
-
-            Document document = areaObj.getDocument(uuid, language);
-            document.lock();
-
-            document.setResourceType(documentType);
-            document.setSourceExtension(extension);
-            document.setMimeType(mimeType);
-
-            // Write Lenya-internal meta-data
-            MetaData lenyaMetaData = document.getMetaData(DocumentImpl.METADATA_NAMESPACE);
-            lenyaMetaData.setValue(DocumentImpl.METADATA_CONTENT_TYPE, "xml");
-
-            if (getLogger().isDebugEnabled()) {
-                getLogger().debug("Create");
-                getLogger().debug("    document:     [" + document + "]");
-            }
-
-            create(stream, document);
-            return document;
-        } catch (Exception e) {
-            throw new DocumentBuildException("call to creator for new document failed", e);
-        }
-    }
-
-    protected void create(InputStream stream, Document document) throws Exception {
-
-        // Read initial contents as DOM
-        if (getLogger().isDebugEnabled())
-            getLogger().debug(
-                    "DefaultCreator::create(), ready to read initial contents from URI [" + stream
-                            + "]");
-
-        copy(getSourceResolver(), stream, document);
-    }
-
-    protected void copy(SourceResolver resolver, InputStream sourceInputStream, Document destination)
-            throws IOException {
-
-        boolean useBuffer = true;
-
-        OutputStream destOutputStream = null;
-        try {
-            destOutputStream = destination.getOutputStream();
-
-            if (useBuffer) {
-                final ByteArrayOutputStream sourceBos = new ByteArrayOutputStream();
-                IOUtils.copy(sourceInputStream, sourceBos);
-                IOUtils.write(sourceBos.toByteArray(), destOutputStream);
-            } else {
-                IOUtils.copy(sourceInputStream, destOutputStream);
-            }
-        } finally {
-            if (destOutputStream != null) {
-                destOutputStream.flush();
-                destOutputStream.close();
-            }
-            if (sourceInputStream != null) {
-                sourceInputStream.close();
-            }
-        }
-    }
-
-    protected void addToSiteManager(String path, Document document, String navigationTitle,
-            boolean visibleInNav) throws PublicationException {
-        addToSiteManager(path, document, navigationTitle, visibleInNav, null);
-    }
-
-    protected void addToSiteManager(String path, Document document, String navigationTitle,
-            boolean visibleInNav, String followingSiblingPath) throws PublicationException {
-        SiteStructure site = document.area().getSite();
-        if (!site.contains(path) && followingSiblingPath != null) {
-            site.add(path, followingSiblingPath);
-        }
-        site.add(path, document);
-        document.getLink().setLabel(navigationTitle);
-        document.getLink().getNode().setVisible(visibleInNav);
-    }
-
-    /**
-     * Template method to copy a document. Override {@link #copyDocumentSource(Document, Document)}
-     * to implement access to a custom repository.
-     * @see org.apache.lenya.cms.publication.DocumentManager#copy(org.apache.lenya.cms.publication.Document,
-     *      org.apache.lenya.cms.publication.DocumentLocator)
-     */
-    public void copy(Document sourceDoc, DocumentLocator destination) throws PublicationException {
-
-        if (!destination.getPublicationId().equals(sourceDoc.getPublication().getId())) {
-            throw new PublicationException("Can't copy to a different publication!");
-        }
-
-        SiteStructure destSite = sourceDoc.getPublication().getArea(destination.getArea())
-                .getSite();
-        String destPath = destination.getPath();
-        if (destSite.contains(destination.getPath(), destination.getLanguage())) {
-            Document destDoc = destSite.getNode(destPath).getLink(destination.getLanguage())
-                    .getDocument();
-            copyDocumentSource(sourceDoc, destDoc);
-            copyInSiteStructure(sourceDoc, destDoc, destPath);
-        } else {
-            add(sourceDoc, destination.getArea(), destPath, destination.getLanguage(), sourceDoc
-                    .getExtension(), sourceDoc.getLink().getLabel(), sourceDoc.getLink().getNode()
-                    .isVisible());
-        }
-
-    }
-
-    protected void copyInSiteStructure(Document sourceDoc, Document destDoc, String destPath)
-            throws PublicationException, DocumentException, SiteException {
-
-        String destArea = destDoc.getArea();
-
-        SiteStructure destSite = sourceDoc.getPublication().getArea(destArea).getSite();
-
-        if (sourceDoc.hasLink()) {
-            if (destDoc.hasLink()) {
-                Link srcLink = sourceDoc.getLink();
-                Link destLink = destDoc.getLink();
-                destLink.setLabel(srcLink.getLabel());
-                destLink.getNode().setVisible(srcLink.getNode().isVisible());
-            } else {
-                String label = sourceDoc.getLink().getLabel();
-                boolean visible = sourceDoc.getLink().getNode().isVisible();
-                if (destSite.contains(sourceDoc.getLink().getNode().getPath())) {
-                    addToSiteManager(destPath, destDoc, label, visible);
-                } else {
-
-                    String followingSiblingPath = null;
-
-                    if (sourceDoc.getPath().equals(destPath)) {
-                        SiteStructure sourceSite = sourceDoc.area().getSite();
-
-                        SiteNode[] sourceSiblings;
-                        SiteNode sourceNode = sourceDoc.getLink().getNode();
-                        if (sourceNode.isTopLevel()) {
-                            sourceSiblings = sourceSite.getTopLevelNodes();
-                        } else if (sourceNode.getParent() != null) {
-                            sourceSiblings = sourceNode.getParent().getChildren();
-                        } else {
-                            sourceSiblings = new SiteNode[1];
-                            sourceSiblings[0] = sourceNode;
-                        }
-
-                        final int sourcePos = Arrays.asList(sourceSiblings).indexOf(sourceNode);
-
-                        int pos = sourcePos;
-                        while (followingSiblingPath == null && pos < sourceSiblings.length) {
-                            String siblingPath = sourceSiblings[pos].getPath();
-                            if (destSite.contains(siblingPath)) {
-                                followingSiblingPath = siblingPath;
-                            }
-                            pos++;
-                        }
-                    }
-
-                    if (followingSiblingPath == null) {
-                        addToSiteManager(destPath, destDoc, label, visible);
-                    } else {
-                        addToSiteManager(destPath, destDoc, label, visible, followingSiblingPath);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * @see org.apache.lenya.cms.publication.DocumentManager#delete(org.apache.lenya.cms.publication.Document)
-     */
-    public void delete(Document document) throws PublicationException {
-        if (!document.exists()) {
-            throw new PublicationException("Document [" + document + "] does not exist!");
-        }
-
-        if (document.hasLink()) {
-            document.getLink().delete();
-        }
-
-        document.delete();
-    }
-
-    /**
-     * @see org.apache.lenya.cms.publication.DocumentManager#move(org.apache.lenya.cms.publication.Document,
-     *      org.apache.lenya.cms.publication.DocumentLocator)
-     */
-    public void move(Document sourceDocument, DocumentLocator destination)
-            throws PublicationException {
-
-        if (!destination.getArea().equals(sourceDocument.getArea())) {
-            throw new PublicationException("Can't move to a different area!");
-        }
-
-        SiteStructure site = sourceDocument.area().getSite();
-        if (site.contains(destination.getPath())) {
-            throw new PublicationException("The path [" + destination
-                    + "] is already contained in this publication!");
-        }
-
-        String label = sourceDocument.getLink().getLabel();
-        boolean visible = sourceDocument.getLink().getNode().isVisible();
-        sourceDocument.getLink().delete();
-
-        site.add(destination.getPath(), sourceDocument);
-        sourceDocument.getLink().setLabel(label);
-        sourceDocument.getLink().getNode().setVisible(visible);
-
-    }
-
-    /**
-     * @see org.apache.lenya.cms.publication.DocumentManager#copyToArea(org.apache.lenya.cms.publication.Document,
-     *      java.lang.String)
-     */
-    public void copyToArea(Document sourceDoc, String destinationArea) throws PublicationException {
-        String language = sourceDoc.getLanguage();
-        copyToVersion(sourceDoc, destinationArea, language);
-    }
-
-    protected void copyToVersion(Document sourceDoc, String destinationArea, String language)
-            throws DocumentException, DocumentBuildException, PublicationException, SiteException {
-
-        Document destDoc;
-        if (sourceDoc.existsAreaVersion(destinationArea)) {
-            destDoc = sourceDoc.getAreaVersion(destinationArea);
-            copyDocumentSource(sourceDoc, destDoc);
-        } else {
-            destDoc = addVersion(sourceDoc, destinationArea, language);
-        }
-
-        if (sourceDoc.hasLink()) {
-            copyInSiteStructure(sourceDoc, destDoc, sourceDoc.getPath());
-        }
-    }
-
-    /**
-     * @see org.apache.lenya.cms.publication.DocumentManager#copyToArea(org.apache.lenya.cms.publication.util.DocumentSet,
-     *      java.lang.String)
-     */
-    public void copyToArea(DocumentSet documentSet, String destinationArea)
-            throws PublicationException {
-        Document[] documents = documentSet.getDocuments();
-        for (int i = 0; i < documents.length; i++) {
-            copyToArea(documents[i], destinationArea);
-        }
-    }
-
-    public void moveAll(Area sourceArea, String sourcePath, Area targetArea, String targetPath)
-            throws PublicationException {
-        SiteStructure site = sourceArea.getSite();
-
-        SiteNode root = site.getNode(sourcePath);
-        List subsite = preOrder(root);
-
-        for (Iterator n = subsite.iterator(); n.hasNext();) {
-            SiteNode node = (SiteNode) n.next();
-            String subPath = node.getPath().substring(sourcePath.length());
-            targetArea.getSite().add(targetPath + subPath);
-        }
-        Collections.reverse(subsite);
-        for (Iterator n = subsite.iterator(); n.hasNext();) {
-            SiteNode node = (SiteNode) n.next();
-            String subPath = node.getPath().substring(sourcePath.length());
-            moveAllLanguageVersions(sourceArea, sourcePath + subPath, targetArea, targetPath
-                    + subPath);
-        }
-    }
-
-    protected List preOrder(SiteNode node) {
-        List list = new ArrayList();
-        list.add(node);
-        SiteNode[] children = node.getChildren();
-        for (int i = 0; i < children.length; i++) {
-            list.addAll(preOrder(children[i]));
-        }
-        return list;
-    }
-
-    public void moveAllLanguageVersions(Area sourceArea, String sourcePath, Area targetArea,
-            String targetPath) throws PublicationException {
-
-        SiteNode sourceNode = sourceArea.getSite().getNode(sourcePath);
-        String[] languages = sourceNode.getLanguages();
-        for (int i = 0; i < languages.length; i++) {
-            Link sourceLink = sourceNode.getLink(languages[i]);
-            String label = sourceLink.getLabel();
-            Document sourceDoc = sourceLink.getDocument();
-            sourceLink.delete();
-
-            Document targetDoc;
-            if (sourceArea.getName().equals(targetArea.getName())) {
-                targetDoc = sourceDoc;
-            } else {
-                targetDoc = addVersion(sourceDoc, targetArea.getName(), sourceDoc.getLanguage());
-                copyRevisions(sourceDoc, targetDoc);
-                sourceDoc.delete();
-            }
-
-            Link link = targetArea.getSite().add(targetPath, targetDoc);
-            link.setLabel(label);
-            assert targetDoc.getLink().getLabel().equals(label);
-        }
-        SiteNode targetNode = targetArea.getSite().getNode(targetPath);
-        targetNode.setVisible(sourceNode.isVisible());
-    }
-
-    protected void copyRevisions(Document sourceDoc, Document targetDoc)
-            throws PublicationException {
-        try {
-            Node targetNode = ((DocumentImpl) targetDoc).getRepositoryNode();
-            targetNode.copyRevisionsFrom(((DocumentImpl) sourceDoc).getRepositoryNode());
-        } catch (Exception e) {
-            throw new PublicationException(e);
-        }
-    }
-
-    public void copyAll(Area sourceArea, String sourcePath, Area targetArea, String targetPath)
-            throws PublicationException {
-
-        SiteStructure site = sourceArea.getSite();
-        SiteNode root = site.getNode(sourcePath);
-
-        List preOrder = preOrder(root);
-        for (Iterator i = preOrder.iterator(); i.hasNext();) {
-            SiteNode node = (SiteNode) i.next();
-            String nodeSourcePath = node.getPath();
-            String nodeTargetPath = targetPath + nodeSourcePath.substring(sourcePath.length());
-            copyAllLanguageVersions(sourceArea, nodeSourcePath, targetArea, nodeTargetPath);
-        }
-    }
-
-    public void copyAllLanguageVersions(Area sourceArea, String sourcePath, Area targetArea,
-            String targetPath) throws PublicationException {
-        Publication pub = sourceArea.getPublication();
-
-        SiteNode sourceNode = sourceArea.getSite().getNode(sourcePath);
-        String[] languages = sourceNode.getLanguages();
-
-        Document targetDoc = null;
-
-        for (int i = 0; i < languages.length; i++) {
-            Document sourceVersion = sourceNode.getLink(languages[i]).getDocument();
-            DocumentLocator targetLocator = DocumentLocator.getLocator(pub.getId(), targetArea
-                    .getName(), targetPath, languages[i]);
-            if (targetDoc == null) {
-                copy(sourceVersion, targetLocator.getLanguageVersion(languages[i]));
-                targetDoc = targetArea.getSite().getNode(targetPath).getLink(languages[i])
-                        .getDocument();
-            } else {
-                targetDoc = addVersion(targetDoc, targetLocator.getArea(), languages[i]);
-                addToSiteManager(targetLocator.getPath(), targetDoc, sourceVersion.getLink()
-                        .getLabel(), sourceVersion.getLink().getNode().isVisible());
-                copyDocumentSource(sourceVersion, targetDoc);
-            }
-        }
-    }
-
-    /**
-     * Copies a document source.
-     * @param sourceDocument The source document.
-     * @param destinationDocument The destination document.
-     * @throws PublicationException when something went wrong.
-     */
-    public void copyDocumentSource(Document sourceDocument, Document destinationDocument)
-            throws PublicationException {
-        copyContent(sourceDocument, destinationDocument);
-        copyMetaData(sourceDocument, destinationDocument);
-    }
-
-    protected void copyContent(Document sourceDocument, Document destinationDocument)
-            throws PublicationException {
-        boolean useBuffer = true;
-
-        OutputStream destOutputStream = null;
-        InputStream sourceInputStream = null;
-        try {
-            try {
-                sourceInputStream = sourceDocument.getInputStream();
-                destOutputStream = destinationDocument.getOutputStream();
-
-                if (useBuffer) {
-                    final ByteArrayOutputStream sourceBos = new ByteArrayOutputStream();
-                    IOUtils.copy(sourceInputStream, sourceBos);
-                    IOUtils.write(sourceBos.toByteArray(), destOutputStream);
-                } else {
-                    IOUtils.copy(sourceInputStream, destOutputStream);
-                }
-            } finally {
-                if (destOutputStream != null) {
-                    destOutputStream.flush();
-                    destOutputStream.close();
-                }
-                if (sourceInputStream != null) {
-                    sourceInputStream.close();
-                }
-            }
-        } catch (Exception e) {
-            throw new PublicationException(e);
-        }
-    }
-
-    /**
-     * Abstract base class for document visitors which operate on a source and target document.
-     */
-    public static abstract class SourceTargetVisitor implements DocumentVisitor {
-
-        private DocumentLocator rootSource;
-        private DocumentLocator rootTarget;
-        private DocumentManager manager;
-
-        /**
-         * Ctor.
-         * @param manager The document manager.
-         * @param source The root source.
-         * @param target The root target.
-         */
-        public SourceTargetVisitor(DocumentManager manager, Document source, DocumentLocator target) {
-            this.manager = manager;
-            this.rootSource = source.getLocator();
-            this.rootTarget = target;
-        }
-
-        /**
-         * @return the root source
-         */
-        protected DocumentLocator getRootSource() {
-            return rootSource;
-        }
-
-        /**
-         * @return the root target
-         */
-        protected DocumentLocator getRootTarget() {
-            return rootTarget;
-        }
-
-        /**
-         * @return the document manager
-         */
-        protected DocumentManager getDocumentManager() {
-            return this.manager;
-        }
-
-        /**
-         * Returns the target corresponding to a source relatively to the root target document.
-         * @param source The source.
-         * @return A document.
-         * @throws DocumentBuildException if the target could not be built.
-         */
-        protected DocumentLocator getTarget(Document source) throws DocumentBuildException {
-            DocumentLocator sourceLocator = source.getLocator();
-            String rootSourcePath = getRootSource().getPath();
-            if (sourceLocator.getPath().equals(rootSourcePath)) {
-                return rootTarget;
-            } else {
-                String relativePath = sourceLocator.getPath().substring(rootSourcePath.length());
-                return rootTarget.getDescendant(relativePath);
-            }
-        }
-    }
-
-    /**
-     * @see org.apache.lenya.cms.publication.DocumentManager#deleteAll(org.apache.lenya.cms.publication.Document)
-     */
-    public void deleteAll(Document document) throws PublicationException {
-        NodeSet subsite = SiteUtil.getSubSite(document.getLink().getNode());
-        for (NodeIterator i = subsite.descending(); i.hasNext();) {
-            SiteNode node = i.next();
-            String[] languages = node.getLanguages();
-            for (int l = 0; l < languages.length; l++) {
-                Document doc = node.getLink(languages[l]).getDocument();
-                delete(doc);
-            }
-        }
-    }
-
-    /**
-     * @see org.apache.lenya.cms.publication.DocumentManager#deleteAllLanguageVersions(org.apache.lenya.cms.publication.Document)
-     */
-    public void deleteAllLanguageVersions(Document document) throws PublicationException {
-        String[] languages = document.getLanguages();
-        for (int i = 0; i < languages.length; i++) {
-            delete(document.getTranslation(languages[i]));
-        }
-    }
-
-    /**
-     * Visitor to delete documents.
-     */
-    public static class DeleteVisitor implements DocumentVisitor {
-
-        private DocumentManager manager;
-
-        /**
-         * Ctor.
-         * @param manager The document manager.
-         */
-        public DeleteVisitor(DocumentManager manager) {
-            this.manager = manager;
-        }
-
-        protected DocumentManager getDocumentManager() {
-            return this.manager;
-        }
-
-        /**
-         * @see org.apache.lenya.cms.publication.util.DocumentVisitor#visitDocument(org.apache.lenya.cms.publication.Document)
-         */
-        public void visitDocument(Document document) throws PublicationException {
-            getDocumentManager().deleteAllLanguageVersions(document);
-        }
-
-    }
-
-    /**
-     * @see org.apache.lenya.cms.publication.DocumentManager#delete(org.apache.lenya.cms.publication.util.DocumentSet)
-     */
-    public void delete(DocumentSet documents) throws PublicationException {
-
-        if (documents.isEmpty()) {
-            return;
-        }
-
-        DocumentSet set = new DocumentSet(documents.getDocuments());
-        sortAscending(set);
-        set.reverse();
-
-        DocumentVisitor visitor = new DeleteVisitor(this);
-        try {
-            set.visit(visitor);
-        } catch (Exception e) {
-            throw new PublicationException(e);
-        }
-
-    }
-
-    /**
-     * @see org.apache.lenya.cms.publication.DocumentManager#move(org.apache.lenya.cms.publication.util.DocumentSet,
-     *      org.apache.lenya.cms.publication.util.DocumentSet)
-     */
-    public void move(DocumentSet sources, DocumentSet destinations) throws PublicationException {
-        copy(sources, destinations);
-        delete(sources);
-        /*
-         * Document[] sourceDocs = sources.getDocuments(); Document[] targetDocs =
-         * destinations.getDocuments();
-         * 
-         * if (sourceDocs.length != targetDocs.length) { throw new PublicationException( "The number
-         * of source and destination documents must be equal!"); }
-         * 
-         * Map source2target = new HashMap(); for (int i = 0; i < sourceDocs.length; i++) {
-         * source2target.put(sourceDocs[i], targetDocs[i]); }
-         * 
-         * DocumentSet sortedSources = new DocumentSet(sourceDocs);
-         * SiteUtil.sortAscending(this.manager, sortedSources); Document[] sortedSourceDocs =
-         * sortedSources.getDocuments();
-         * 
-         * for (int i = 0; i < sortedSourceDocs.length; i++) { move(sortedSourceDocs[i], (Document)
-         * source2target.get(sortedSourceDocs[i])); }
-         */
-    }
-
-    /**
-     * @see org.apache.lenya.cms.publication.DocumentManager#copy(org.apache.lenya.cms.publication.util.DocumentSet,
-     *      org.apache.lenya.cms.publication.util.DocumentSet)
-     */
-    public void copy(DocumentSet sources, DocumentSet destinations) throws PublicationException {
-        Document[] sourceDocs = sources.getDocuments();
-        Document[] targetDocs = destinations.getDocuments();
-
-        if (sourceDocs.length != targetDocs.length) {
-            throw new PublicationException(
-                    "The number of source and destination documents must be equal!");
-        }
-
-        Map source2target = new HashMap();
-        for (int i = 0; i < sourceDocs.length; i++) {
-            source2target.put(sourceDocs[i], targetDocs[i]);
-        }
-
-        DocumentSet sortedSources = new DocumentSet(sourceDocs);
-        sortAscending(sortedSources);
-        Document[] sortedSourceDocs = sortedSources.getDocuments();
-
-        for (int i = 0; i < sortedSourceDocs.length; i++) {
-            copy(sortedSourceDocs[i], ((Document) source2target.get(sortedSourceDocs[i]))
-                    .getLocator());
-        }
-    }
-
-    protected void sortAscending(DocumentSet set) throws PublicationException {
-
-        if (!set.isEmpty()) {
-
-            Document[] docs = set.getDocuments();
-            int n = docs.length;
-
-            Publication pub = docs[0].getPublication();
-            SiteManager siteManager = (SiteManager) WebAppContextUtils
-                    .getCurrentWebApplicationContext().getBean(
-                            SiteManager.class.getName() + "/" + pub.getSiteManagerHint());
-
-            Set nodes = new HashSet();
-            for (int i = 0; i < docs.length; i++) {
-                nodes.add(docs[i].getLink().getNode());
-            }
-
-            SiteNode[] ascending = siteManager.sortAscending((SiteNode[]) nodes
-                    .toArray(new SiteNode[nodes.size()]));
-
-            set.clear();
-            for (int i = 0; i < ascending.length; i++) {
-                for (int d = 0; d < docs.length; d++) {
-                    if (docs[d].getPath().equals(ascending[i].getPath())) {
-                        set.add(docs[d]);
-                    }
-                }
-            }
-
-            if (set.getDocuments().length != n) {
-                throw new IllegalStateException("Number of documents has changed!");
-            }
-
-        }
-    }
-
-    public Document addVersion(Document sourceDocument, String area, String language,
-            boolean addToSiteStructure) throws DocumentBuildException, PublicationException {
-        Document document = addVersion(sourceDocument, area, language);
-
-        if (addToSiteStructure && sourceDocument.hasLink()) {
-            String path = sourceDocument.getPath();
-            boolean visible = sourceDocument.getLink().getNode().isVisible();
-            addToSiteManager(path, document, sourceDocument.getLink().getLabel(), visible);
-        }
-
-        return document;
-    }
-
-    public Document addVersion(Document sourceDocument, String area, String language)
-            throws DocumentBuildException, DocumentException, PublicationException {
-        Document document = add(sourceDocument.getResourceType(), sourceDocument.getUUID(),
-                sourceDocument.getInputStream(), sourceDocument.getPublication(), area, language,
-                sourceDocument.getSourceExtension(), sourceDocument.getMimeType());
-        copyMetaData(sourceDocument, document);
-
-        return document;
-    }
-
-    public SourceResolver getSourceResolver() {
-        return sourceResolver;
-    }
-
-    public void setSourceResolver(SourceResolver sourceResolver) {
-        this.sourceResolver = sourceResolver;
-    }
-
-    public UUIDGenerator getUuidGenerator() {
-        return uuidGenerator;
-    }
-
-    public void setUuidGenerator(UUIDGenerator uuidGenerator) {
-        this.uuidGenerator = uuidGenerator;
-    }
-
-    public NodeFactory getNodeFactory() {
-        return nodeFactory;
-    }
-
-    public void setNodeFactory(NodeFactory nodeFactory) {
-        this.nodeFactory = nodeFactory;
-    }
-
-}