Index: src/test/java/org/apache/jackrabbit/core/NodeImplTest.java
===================================================================
--- src/test/java/org/apache/jackrabbit/core/NodeImplTest.java	(revisión: 795746)
+++ src/test/java/org/apache/jackrabbit/core/NodeImplTest.java	(copia de trabajo)
@@ -18,14 +18,17 @@
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.apache.jackrabbit.JcrConstants;
 import org.apache.jackrabbit.test.AbstractJCRTest;
 import org.apache.jackrabbit.test.NotExecutableException;
+import org.apache.jackrabbit.uuid.UUID;
 import org.apache.jackrabbit.api.jsr283.security.AccessControlManager;
 import org.apache.jackrabbit.api.jsr283.security.AccessControlPolicyIterator;
 import org.apache.jackrabbit.api.jsr283.security.AccessControlPolicy;
 import org.apache.jackrabbit.api.jsr283.security.Privilege;
 import org.apache.jackrabbit.core.security.authorization.JackrabbitAccessControlList;
 
+import javax.jcr.ItemExistsException;
 import javax.jcr.Node;
 import javax.jcr.Session;
 import javax.jcr.RepositoryException;
@@ -125,4 +128,31 @@
             changeReadPermission(principal, n, true);
         }
     }
+    
+    public void testAddNodeUuid() throws RepositoryException, NotExecutableException {
+        String uuid = "f81d4fae-7dec-11d0-a765-00a0c91e6bf6";
+    	Node n = testRootNode.addNode(nodeName1);
+        Node testNode = ((NodeImpl) n).addNodeWithUuid(nodeName2, uuid);
+        testNode.addMixin(JcrConstants.MIX_REFERENCEABLE);
+        testRootNode.save();
+        assertEquals("Node UUID should be: "+uuid, uuid, testNode.getUUID());
+    }
+    
+    public void testAddNodeUuidCollision() throws RepositoryException, NotExecutableException {
+        String uuid = "f81d4fae-7dec-11d0-a765-00a0c91e6bf6";
+    	Node n = testRootNode.addNode(nodeName1);
+        Node testNode1 = ((NodeImpl) n).addNodeWithUuid(nodeName2, uuid);
+        testNode1.addMixin(JcrConstants.MIX_REFERENCEABLE);
+        testRootNode.save();
+        boolean collisionDetected = false;
+        
+        try {
+            Node testNode2 = ((NodeImpl) n).addNodeWithUuid(nodeName2, uuid);
+            testNode1.addMixin(JcrConstants.MIX_REFERENCEABLE);
+            testRootNode.save();
+        } catch (ItemExistsException iee) {
+            collisionDetected = true;
+        }
+        assertTrue("Node collision detected: "+uuid, collisionDetected);
+    }    
 }
\ No newline at end of file
Index: src/test/java/org/apache/jackrabbit/core/version/TestAll.java
===================================================================
--- src/test/java/org/apache/jackrabbit/core/version/TestAll.java	(revisión: 795746)
+++ src/test/java/org/apache/jackrabbit/core/version/TestAll.java	(copia de trabajo)
@@ -37,6 +37,7 @@
         suite.addTestSuite(RemoveVersionLabelTest.class);
         suite.addTestSuite(RestoreTest.class);
         suite.addTestSuite(VersionIteratorImplTest.class);
+        suite.addTestSuite(CheckinCalendarTest.class);
         return suite;
     }
 }
Index: src/main/java/org/apache/jackrabbit/core/NodeImpl.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/NodeImpl.java	(revisión: 795746)
+++ src/main/java/org/apache/jackrabbit/core/NodeImpl.java	(copia de trabajo)
@@ -16,6 +16,52 @@
  */
 package org.apache.jackrabbit.core;
 
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.Calendar;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import javax.jcr.AccessDeniedException;
+import javax.jcr.InvalidItemStateException;
+import javax.jcr.Item;
+import javax.jcr.ItemExistsException;
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.ItemVisitor;
+import javax.jcr.MergeException;
+import javax.jcr.NamespaceException;
+import javax.jcr.NoSuchWorkspaceException;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.Value;
+import javax.jcr.ValueFormatException;
+import javax.jcr.lock.Lock;
+import javax.jcr.lock.LockException;
+import javax.jcr.nodetype.ConstraintViolationException;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
+import javax.jcr.nodetype.NodeDefinition;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.nodetype.PropertyDefinition;
+import javax.jcr.version.OnParentVersionAction;
+import javax.jcr.version.Version;
+import javax.jcr.version.VersionException;
+import javax.jcr.version.VersionHistory;
+import javax.jcr.version.VersionIterator;
+
+import org.apache.jackrabbit.api.jsr283.Binary;
+import org.apache.jackrabbit.api.jsr283.lock.LockManager;
+import org.apache.jackrabbit.api.jsr283.version.VersionManager;
 import org.apache.jackrabbit.commons.iterator.NodeIteratorAdapter;
 import org.apache.jackrabbit.commons.iterator.PropertyIteratorAdapter;
 import org.apache.jackrabbit.core.nodetype.EffectiveNodeType;
@@ -29,24 +75,25 @@
 import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
 import org.apache.jackrabbit.core.nodetype.PropDef;
 import org.apache.jackrabbit.core.nodetype.PropertyDefinitionImpl;
+import org.apache.jackrabbit.core.security.authorization.Permission;
+import org.apache.jackrabbit.core.state.ChildNodeEntry;
 import org.apache.jackrabbit.core.state.ItemState;
 import org.apache.jackrabbit.core.state.ItemStateException;
 import org.apache.jackrabbit.core.state.NodeReferences;
 import org.apache.jackrabbit.core.state.NodeReferencesId;
 import org.apache.jackrabbit.core.state.NodeState;
 import org.apache.jackrabbit.core.state.PropertyState;
-import org.apache.jackrabbit.core.state.ChildNodeEntry;
 import org.apache.jackrabbit.core.value.InternalValue;
 import org.apache.jackrabbit.core.version.DateVersionSelector;
 import org.apache.jackrabbit.core.version.InternalFreeze;
 import org.apache.jackrabbit.core.version.InternalFrozenNode;
 import org.apache.jackrabbit.core.version.InternalFrozenVersionHistory;
+import org.apache.jackrabbit.core.version.InternalVersion;
+import org.apache.jackrabbit.core.version.InternalVersionHistory;
 import org.apache.jackrabbit.core.version.LabelVersionSelector;
 import org.apache.jackrabbit.core.version.VersionImpl;
 import org.apache.jackrabbit.core.version.VersionSelector;
-import org.apache.jackrabbit.core.version.InternalVersionHistory;
-import org.apache.jackrabbit.core.version.InternalVersion;
-import org.apache.jackrabbit.core.security.authorization.Permission;
+import org.apache.jackrabbit.core.xml.NodeInfo;
 import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.Path;
 import org.apache.jackrabbit.spi.commons.conversion.MalformedPathException;
@@ -57,54 +104,9 @@
 import org.apache.jackrabbit.util.ChildrenCollectorFilter;
 import org.apache.jackrabbit.uuid.UUID;
 import org.apache.jackrabbit.value.ValueHelper;
-import org.apache.jackrabbit.api.jsr283.Binary;
-import org.apache.jackrabbit.api.jsr283.version.VersionManager;
-import org.apache.jackrabbit.api.jsr283.lock.LockManager;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.jcr.AccessDeniedException;
-import javax.jcr.InvalidItemStateException;
-import javax.jcr.Item;
-import javax.jcr.ItemExistsException;
-import javax.jcr.ItemNotFoundException;
-import javax.jcr.ItemVisitor;
-import javax.jcr.MergeException;
-import javax.jcr.NamespaceException;
-import javax.jcr.NoSuchWorkspaceException;
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.PathNotFoundException;
-import javax.jcr.Property;
-import javax.jcr.PropertyIterator;
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-import javax.jcr.UnsupportedRepositoryOperationException;
-import javax.jcr.Value;
-import javax.jcr.ValueFormatException;
-import javax.jcr.lock.Lock;
-import javax.jcr.lock.LockException;
-import javax.jcr.nodetype.ConstraintViolationException;
-import javax.jcr.nodetype.NoSuchNodeTypeException;
-import javax.jcr.nodetype.NodeDefinition;
-import javax.jcr.nodetype.NodeType;
-import javax.jcr.nodetype.PropertyDefinition;
-import javax.jcr.version.OnParentVersionAction;
-import javax.jcr.version.Version;
-import javax.jcr.version.VersionException;
-import javax.jcr.version.VersionHistory;
-import javax.jcr.version.VersionIterator;
-import java.io.InputStream;
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.BitSet;
-import java.util.Calendar;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
 /**
  * <code>NodeImpl</code> implements the <code>Node</code> interface.
  */
@@ -2136,6 +2138,49 @@
 
         return internalAddNode(relPath, null);
     }
+ 
+    /**
+     * Same as <code>{@link Node#addNode(String)}</code> except
+     * this method takes an additional <code>uuid</code> argument.
+     * <b>Important Notice:</b> Use this method with caution!
+     * @param relPath      path of the new node
+     * @param nodeName     name of the new node
+     * @param nodeTypeName name of the new node's node type or <code>null</code>
+     *                     if it should be determined automatically
+     * @param uuid         uuid of the new node or <code>null</code>
+     * @return the newly added node
+     * @throws ItemExistsException
+     * @throws PathNotFoundException
+     * @throws VersionException
+     * @throws ConstraintViolationException
+     * @throws LockException
+     * @throws RepositoryException
+     */
+    public synchronized Node addNodeWithUuid(String relPath, String uuid)
+    		throws ItemExistsException, PathNotFoundException, VersionException,
+    		ConstraintViolationException, LockException, RepositoryException {
+    	// check state of this instance
+    	sanityCheck();
+    	
+    	//if (!isNodeType(NameConstants.MIX_REFERENCEABLE)) {
+        //    throw new UnsupportedRepositoryOperationException();
+        //}
+    	
+    	// Test for existing UUID
+    	// @see SessionImporter.startNode(NodeInfo nodeInfo, List propInfos)
+    	Node uuidNode;
+    	try {
+    		uuidNode = session.getNodeByUUID(uuid);
+    	} catch (ItemNotFoundException infe) {
+    		uuidNode = null;
+    	}
+    	
+    	if (uuidNode != null) {
+    		throw new ItemExistsException(uuid.toString());
+    	}
+    	    	
+    	return internalAddNode(relPath, null, new NodeId(new UUID(uuid)));
+    }
 
     /**
      * {@inheritDoc}
@@ -2156,6 +2201,56 @@
     }
 
     /**
+     * Same as <code>{@link Node#addNode(String, String)}</code> except
+     * this method takes an additional <code>uuid</code> argument.
+     * <b>Important Notice:</b> Use this method with caution!
+     * @param relPath      path of the new node
+     * @param nodeName     name of the new node
+     * @param nodeTypeName name of the new node's node type or <code>null</code>
+     *                     if it should be determined automatically
+     * @param uuid         uuid of the new node or <code>null</code>
+     * @return the newly added node
+     * @throws ItemExistsException
+     * @throws PathNotFoundException
+     * @throws NoSuchNodeTypeException
+     * @throws VersionException
+     * @throws ConstraintViolationException
+     * @throws LockException
+     * @throws RepositoryException
+     */
+    public synchronized Node addNodeWithUuid(String relPath, String nodeTypeName, String uuid)
+    		throws ItemExistsException, PathNotFoundException,
+    		NoSuchNodeTypeException, VersionException,
+    		ConstraintViolationException, LockException, RepositoryException {
+    	// check state of this instance
+    	sanityCheck();
+    	
+    	//if (!isNodeType(NameConstants.MIX_REFERENCEABLE)) {
+        //    throw new UnsupportedRepositoryOperationException();
+        //}
+    	
+    	// Test for existing UUID
+    	// @see SessionImporter.startNode(NodeInfo nodeInfo, List propInfos)
+    	Node uuidNode;
+    	try {
+    		uuidNode = session.getNodeByUUID(uuid);
+    	} catch (ItemNotFoundException infe) {
+    		uuidNode = null;
+    	}
+    	
+    	if (uuidNode != null) {
+    		throw new ItemExistsException(uuid.toString());
+    	}
+    	
+    	NodeTypeImpl nt = (NodeTypeImpl) session.getNodeTypeManager().getNodeType(nodeTypeName);
+    	if (nt.isMixin()) {
+    		throw new RepositoryException(nodeTypeName + ": not a primary node type");
+    	}
+    	
+    	return internalAddNode(relPath, nt, new NodeId(new UUID(uuid)));
+    }
+
+    /**
      * {@inheritDoc}
      */
     public void orderBefore(String srcName, String destName)
@@ -3300,43 +3395,49 @@
     public Version checkin()
             throws VersionException, UnsupportedRepositoryOperationException,
             InvalidItemStateException, LockException, RepositoryException {
+        return checkin(null);
+    }
+
+    public Version checkin(Calendar cal)
+            throws VersionException, UnsupportedRepositoryOperationException,
+            InvalidItemStateException, LockException, RepositoryException {
         // check state of this instance
         sanityCheck();
-
+        
         // check if versionable
         boolean isFull = checkVersionable();
-
+        
         // check if checked out
         if (!internalIsCheckedOut()) {
-            String msg = this + ": Node is already checked-in. ignoring.";
-            log.debug(msg);
-            return getBaseVersion();
+        	String msg = this + ": Node is already checked-in. ignoring.";
+        	log.debug(msg);
+        	return getBaseVersion();
         }
 
         // check lock status, holds and permissions
         int options = ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD | ItemValidator.CHECK_PENDING_CHANGES_ON_NODE;
         session.getValidator().checkModify(this, options, Permission.VERSION_MNGMT);
-
-        Version v = session.getVersionManager().checkin(this);
+        
+        Version v = session.getVersionManager().checkin(this, cal);
         boolean success = false;
         try {
-            internalSetProperty(NameConstants.JCR_ISCHECKEDOUT, InternalValue.create(false));
-            if (isFull) {
-                internalSetProperty(NameConstants.JCR_BASEVERSION, InternalValue.create(new UUID(v.getUUID())));
-                internalSetProperty(NameConstants.JCR_PREDECESSORS, InternalValue.EMPTY_ARRAY, PropertyType.REFERENCE);
-            }
-            save();
-            success = true;
+        	internalSetProperty(NameConstants.JCR_ISCHECKEDOUT, InternalValue.create(false));
+        	if (isFull) {
+        		internalSetProperty(NameConstants.JCR_BASEVERSION, InternalValue.create(new UUID(v.getUUID())));
+        		internalSetProperty(NameConstants.JCR_PREDECESSORS, InternalValue.EMPTY_ARRAY, PropertyType.REFERENCE);
+        	}
+        	save();
+        	success = true;
         } finally {
-            if (!success) {
-                try {
-                    // TODO: need to revert changes made within the version manager as well.
-                    refresh(false);
-                } catch (RepositoryException e) {
-                    // cleanup failed
-                    log.error("Error while cleaning up after failed Node.checkin", e);
-                }
-            }
+        	if (!success) {
+        		try {
+        			// TODO: need to revert changes made within the version manager as well.
+        			refresh(false);
+        		} catch (RepositoryException e) {
+        			// cleanup failed
+        			log.error("Error while cleaning up after failed Node.checkin", e);
+        		}
+        	}
         }
         return v;
     }
Index: src/main/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java	(revisión: 795746)
+++ src/main/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java	(copia de trabajo)
@@ -53,6 +53,7 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.Calendar;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
@@ -277,6 +278,10 @@
      * item-reading listeners in the observation thread.
      */
     public Version checkin(final NodeImpl node) throws RepositoryException {
+        return checkin(node, null);
+    }
+    
+    public Version checkin(final NodeImpl node, final Calendar cal) throws RepositoryException {
         InternalVersion version = (InternalVersion)
                 escFactory.doSourced((SessionImpl) node.getSession(), new SourcedTarget() {
             public Object run() throws RepositoryException {
@@ -286,11 +291,11 @@
                     // the property
                     String histUUID = node.getProperty(NameConstants.JCR_VERSIONHISTORY).getString();
                     vh = getVersionHistory(NodeId.valueOf(histUUID));
-                    return checkin((InternalVersionHistoryImpl) vh, node, false);
+                    return checkin((InternalVersionHistoryImpl) vh, node, false, cal);
                 } else {
                     // in simple versioning the history id needs to be calculated
                     vh = getVersionHistoryOfNode(node.getNodeId());
-                    return checkin((InternalVersionHistoryImpl) vh, node, true);
+                    return checkin((InternalVersionHistoryImpl) vh, node, true, cal);
                 }
             }
         });
Index: src/main/java/org/apache/jackrabbit/core/version/AbstractVersionManager.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/version/AbstractVersionManager.java	(revisión: 795746)
+++ src/main/java/org/apache/jackrabbit/core/version/AbstractVersionManager.java	(copia de trabajo)
@@ -16,6 +16,8 @@
  */
 package org.apache.jackrabbit.core.version;
 
+import java.util.Calendar;
+
 import org.apache.jackrabbit.core.NodeId;
 import org.apache.jackrabbit.core.NodeImpl;
 import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
@@ -431,19 +433,25 @@
     protected InternalVersion checkin(InternalVersionHistoryImpl history,
                                       NodeImpl node, boolean simple)
             throws RepositoryException {
-        WriteOperation operation = startWriteOperation();
-        try {
-            String versionName = calculateCheckinVersionName(history, node, simple);
-            InternalVersionImpl v = history.checkin(NameFactoryImpl.getInstance().create("", versionName), node);
-            operation.save();
-            return v;
-        } catch (ItemStateException e) {
-            throw new RepositoryException(e);
-        } finally {
-            operation.close();
-        }
+        return checkin(history, node, simple, null);
     }
 
+    protected InternalVersion checkin(InternalVersionHistoryImpl history,
+            							NodeImpl node, boolean simple, Calendar cal)
+    		throws RepositoryException {
+    	WriteOperation operation = startWriteOperation();
+    	try {
+    		String versionName = calculateCheckinVersionName(history, node, simple);
+    		InternalVersionImpl v = history.checkin(NameFactoryImpl.getInstance().create("", versionName), node, cal);
+    		operation.save();
+    		return v;
+    	} catch (ItemStateException e) {
+    		throw new RepositoryException(e);
+    	} finally {
+    		operation.close();
+    	}
+    }
+    
     /**
      * Calculates the name of the new version that will be created by a
      * checkin call. The name is determined as follows:
Index: src/main/java/org/apache/jackrabbit/core/version/XAVersionManager.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/version/XAVersionManager.java	(revisión: 795746)
+++ src/main/java/org/apache/jackrabbit/core/version/XAVersionManager.java	(copia de trabajo)
@@ -16,6 +16,7 @@
  */
 package org.apache.jackrabbit.core.version;
 
+import java.util.Calendar;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
@@ -160,6 +161,10 @@
      * {@inheritDoc}
      */
     public Version checkin(NodeImpl node) throws RepositoryException {
+        return checkin(node, null);
+    }
+
+    public Version checkin(NodeImpl node, Calendar cal) throws RepositoryException {
         if (isInXA()) {
             InternalVersionHistory vh;
             InternalVersion version;
@@ -168,17 +173,17 @@
                 // the property
                 String histUUID = node.getProperty(NameConstants.JCR_VERSIONHISTORY).getString();
                 vh = getVersionHistory(NodeId.valueOf(histUUID));
-                version = checkin((InternalVersionHistoryImpl) vh, node, false);
+                version = checkin((InternalVersionHistoryImpl) vh, node, false, cal);
             } else {
                 // in simple versioning the history id needs to be calculated
                 vh = getVersionHistoryOfNode(node.getNodeId());
-                version = checkin((InternalVersionHistoryImpl) vh, node, true);
+                version = checkin((InternalVersionHistoryImpl) vh, node, true, cal);
             }
             return (Version) ((SessionImpl) node.getSession()).getNodeById(version.getId());
         }
-        return vMgr.checkin(node);
+        return vMgr.checkin(node, cal);
     }
-
+    
     /**
      * {@inheritDoc}
      */
@@ -409,7 +414,24 @@
         }
         return version;
     }
-
+    
+    protected InternalVersion checkin(InternalVersionHistoryImpl history,
+            		NodeImpl node, boolean simple, Calendar cal)
+    		throws RepositoryException {
+    	
+    	if (history.getVersionManager() != this) {
+    		history = makeLocalCopy(history);
+    		xaItems.put(history.getId(), history);
+    	}
+    	InternalVersion version = super.checkin(history, node, simple, cal);
+    	NodeId frozenNodeId = version.getFrozenNodeId();
+    	InternalVersionItem frozenNode = createInternalVersionItem(frozenNodeId);
+    	if (frozenNode != null) {
+    		xaItems.put(frozenNodeId, frozenNode);
+    	}
+    	return version;
+    }
+    
     /**
      * {@inheritDoc}
      * <p/>
Index: src/main/java/org/apache/jackrabbit/core/version/VersionManager.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/version/VersionManager.java	(revisión: 795746)
+++ src/main/java/org/apache/jackrabbit/core/version/VersionManager.java	(copia de trabajo)
@@ -16,6 +16,8 @@
  */
 package org.apache.jackrabbit.core.version;
 
+import java.util.Calendar;
+
 import org.apache.jackrabbit.core.NodeImpl;
 import org.apache.jackrabbit.core.NodeId;
 import org.apache.jackrabbit.core.state.NodeState;
@@ -65,6 +67,8 @@
      * @throws RepositoryException if an error occurs
      */
     Version checkin(NodeImpl node) throws RepositoryException;
+    
+    Version checkin(NodeImpl node, Calendar cal) throws RepositoryException;
 
     /**
      * Removes the specified version from the given version history.
Index: src/main/java/org/apache/jackrabbit/core/version/InternalVersionHistoryImpl.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/version/InternalVersionHistoryImpl.java	(revisión: 795746)
+++ src/main/java/org/apache/jackrabbit/core/version/InternalVersionHistoryImpl.java	(copia de trabajo)
@@ -494,60 +494,69 @@
      */
     InternalVersionImpl checkin(Name name, NodeImpl src)
             throws RepositoryException {
+        return checkin(name, src, null);
+    }
+    
+    InternalVersionImpl checkin(Name name, NodeImpl src, Calendar cal)
+    		throws RepositoryException {
 
-        // copy predecessors from src node
-        InternalValue[] predecessors;
-        if (src.hasProperty(NameConstants.JCR_PREDECESSORS)) {
-            Value[] preds = src.getProperty(NameConstants.JCR_PREDECESSORS).getValues();
-            predecessors = new InternalValue[preds.length];
-            for (int i = 0; i < preds.length; i++) {
-                UUID predId = UUID.fromString(preds[i].getString());
-                // check if version exist
-                if (!nameCache.containsValue(new NodeId(predId))) {
-                    throw new RepositoryException("invalid predecessor in source node");
-                }
-                predecessors[i] = InternalValue.create(predId);
-            }
-        } else {
-            // with simple versioning, the node does not contain a predecessors
-            // property and we just use the 'head' version as predecessor
-            Iterator iter = nameCache.values().iterator();
-            NodeId last = null;
-            while (iter.hasNext()) {
-                last = (NodeId) iter.next();
-            }
-            if (last == null) {
-                // should never happen
-                last = rootVersion.getId();
-            }
-            predecessors = new InternalValue[]{InternalValue.create(last.getUUID())};
-        }
-
-        NodeId versionId = new NodeId(UUID.randomUUID());
-        NodeStateEx vNode = node.addNode(name, NameConstants.NT_VERSION, versionId, true);
-
-        // initialize 'created', 'predecessors' and 'successors'
-        vNode.setPropertyValue(NameConstants.JCR_CREATED, InternalValue.create(getCurrentTime()));
-        vNode.setPropertyValues(NameConstants.JCR_PREDECESSORS, PropertyType.REFERENCE, predecessors);
-        vNode.setPropertyValues(NameConstants.JCR_SUCCESSORS, PropertyType.REFERENCE, InternalValue.EMPTY_ARRAY);
-
-        // checkin source node
-        InternalFrozenNodeImpl.checkin(vNode, NameConstants.JCR_FROZENNODE, src);
-
-        // update version graph
-        InternalVersionImpl version = new InternalVersionImpl(this, vNode, name);
-        version.internalAttach();
-
-        // and store
-        node.store();
-
-        vMgr.versionCreated(version);
-
-        // update cache
-        versionCache.put(version.getId(), version);
-        nameCache.put(version.getName(), version.getId());
-
-        return version;
+    	// copy predecessors from src node
+    	InternalValue[] predecessors;
+    	if (src.hasProperty(NameConstants.JCR_PREDECESSORS)) {
+    		Value[] preds = src.getProperty(NameConstants.JCR_PREDECESSORS).getValues();
+    		predecessors = new InternalValue[preds.length];
+    		for (int i = 0; i < preds.length; i++) {
+    			UUID predId = UUID.fromString(preds[i].getString());
+    			// check if version exist
+    			if (!nameCache.containsValue(new NodeId(predId))) {
+    				throw new RepositoryException("invalid predecessor in source node");
+    			}
+    			predecessors[i] = InternalValue.create(predId);
+    		}
+    	} else {
+    		// with simple versioning, the node does not contain a predecessors
+    		// property and we just use the 'head' version as predecessor
+    		Iterator iter = nameCache.values().iterator();
+    		NodeId last = null;
+    		while (iter.hasNext()) {
+    			last = (NodeId) iter.next();
+    		}
+    		if (last == null) {
+    			// should never happen
+    			last = rootVersion.getId();
+    		}
+    		predecessors = new InternalValue[]{InternalValue.create(last.getUUID())};
+    	}
+    	
+    	NodeId versionId = new NodeId(UUID.randomUUID());
+    	NodeStateEx vNode = node.addNode(name, NameConstants.NT_VERSION, versionId, true);
+    	
+    	// initialize 'created', 'predecessors' and 'successors'
+    	if (cal == null) {
+    	    vNode.setPropertyValue(NameConstants.JCR_CREATED, InternalValue.create(getCurrentTime()));
+    	} else {
+    	    vNode.setPropertyValue(NameConstants.JCR_CREATED, InternalValue.create(cal));
+    	}
+    	vNode.setPropertyValues(NameConstants.JCR_PREDECESSORS, PropertyType.REFERENCE, predecessors);
+    	vNode.setPropertyValues(NameConstants.JCR_SUCCESSORS, PropertyType.REFERENCE, InternalValue.EMPTY_ARRAY);
+    	
+    	// checkin source node
+    	InternalFrozenNodeImpl.checkin(vNode, NameConstants.JCR_FROZENNODE, src);
+    	
+    	// update version graph
+    	InternalVersionImpl version = new InternalVersionImpl(this, vNode, name);
+    	version.internalAttach();
+    	
+    	// and store
+    	node.store();
+    	
+    	vMgr.versionCreated(version);
+    	
+    	// update cache
+    	versionCache.put(version.getId(), version);
+    	nameCache.put(version.getName(), version.getId());
+    	
+    	return version;
     }
 
     /**
