Index: src/main/java/org/apache/jackrabbit/core/NodeImpl.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/NodeImpl.java	(revision 793403)
+++ src/main/java/org/apache/jackrabbit/core/NodeImpl.java	(working copy)
@@ -2136,6 +2136,19 @@
 
         return internalAddNode(relPath, null);
     }
+ 
+    public synchronized Node addNode(String relPath, UUID uuid)
+    		throws ItemExistsException, PathNotFoundException, VersionException,
+    		ConstraintViolationException, LockException, RepositoryException {
+    	// check state of this instance
+    	sanityCheck();
+    	
+    	//if (!isNodeType(NameConstants.MIX_REFERENCEABLE)) {
+        //    throw new UnsupportedRepositoryOperationException();
+        //}
+    	
+    	return internalAddNode(relPath, null, new NodeId(uuid));
+    }
 
     /**
      * {@inheritDoc}
@@ -2155,6 +2168,25 @@
         return internalAddNode(relPath, nt);
     }
 
+    public synchronized Node addNode(String relPath, String nodeTypeName, UUID uuid)
+    		throws ItemExistsException, PathNotFoundException,
+    		NoSuchNodeTypeException, VersionException,
+    		ConstraintViolationException, LockException, RepositoryException {
+    	// check state of this instance
+    	sanityCheck();
+    	
+    	//if (!isNodeType(NameConstants.MIX_REFERENCEABLE)) {
+        //    throw new UnsupportedRepositoryOperationException();
+        //}
+    	
+    	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(uuid));
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -3341,6 +3373,50 @@
         return v;
     }
 
+    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();
+        }
+
+        // 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, 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;
+        } 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);
+        		}
+        	}
+        }
+        return v;
+    }
+
     /**
      * {@inheritDoc}
      */
Index: src/main/java/org/apache/jackrabbit/core/version/AbstractVersionManager.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/version/AbstractVersionManager.java	(revision 793403)
+++ src/main/java/org/apache/jackrabbit/core/version/AbstractVersionManager.java	(working copy)
@@ -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;
@@ -444,6 +446,22 @@
         }
     }
 
+    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/InternalVersionHistoryImpl.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/version/InternalVersionHistoryImpl.java	(revision 793403)
+++ src/main/java/org/apache/jackrabbit/core/version/InternalVersionHistoryImpl.java	(working copy)
@@ -549,6 +549,64 @@
 
         return version;
     }
+    
+    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(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;
+    }
 
     /**
      * Creates a new version history below the given parent node and with
Index: src/main/java/org/apache/jackrabbit/core/version/VersionManager.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/version/VersionManager.java	(revision 793403)
+++ src/main/java/org/apache/jackrabbit/core/version/VersionManager.java	(working copy)
@@ -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/VersionManagerImpl.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java	(revision 793403)
+++ src/main/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java	(working copy)
@@ -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;
@@ -298,6 +299,29 @@
         return (VersionImpl)
                 ((SessionImpl) node.getSession()).getNodeById(version.getId());
     }
+    
+    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 {
+                InternalVersionHistory vh;
+                if (node.isNodeType(NameConstants.MIX_VERSIONABLE)) {
+                    // in full versioning, the history id can be retrieved via
+                    // the property
+                    String histUUID = node.getProperty(NameConstants.JCR_VERSIONHISTORY).getString();
+                    vh = getVersionHistory(NodeId.valueOf(histUUID));
+                    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, cal);
+                }
+            }
+        });
+
+        return (VersionImpl)
+                ((SessionImpl) node.getSession()).getNodeById(version.getId());
+    }
 
     /**
      * {@inheritDoc}
Index: src/main/java/org/apache/jackrabbit/core/version/XAVersionManager.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/version/XAVersionManager.java	(revision 793403)
+++ src/main/java/org/apache/jackrabbit/core/version/XAVersionManager.java	(working copy)
@@ -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;
@@ -179,6 +180,26 @@
         return vMgr.checkin(node);
     }
 
+    public Version checkin(NodeImpl node, Calendar cal) throws RepositoryException {
+        if (isInXA()) {
+            InternalVersionHistory vh;
+            InternalVersion version;
+            if (node.isNodeType(NameConstants.MIX_VERSIONABLE)) {
+                // in full versioning, the history id can be retrieved via
+                // the property
+                String histUUID = node.getProperty(NameConstants.JCR_VERSIONHISTORY).getString();
+                vh = getVersionHistory(NodeId.valueOf(histUUID));
+                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, cal);
+            }
+            return (Version) ((SessionImpl) node.getSession()).getNodeById(version.getId());
+        }
+        return vMgr.checkin(node, cal);
+    }
+    
     /**
      * {@inheritDoc}
      */
@@ -409,7 +430,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/test/java/org/apache/jackrabbit/core/NodeImplTest.java
===================================================================
--- src/test/java/org/apache/jackrabbit/core/NodeImplTest.java	(revision 793403)
+++ src/test/java/org/apache/jackrabbit/core/NodeImplTest.java	(working copy)
@@ -18,8 +18,10 @@
 
 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;
@@ -125,4 +127,14 @@
             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).addNode(nodeName2, new UUID(uuid));
+        testNode.addMixin(JcrConstants.MIX_REFERENCEABLE);
+        testRootNode.save();
+        System.out.println("Es: "+testNode.getUUID());
+        assertEquals("Node UUID should be: "+uuid, uuid, testNode.getUUID());
+    }
 }
\ No newline at end of file
Index: src/test/java/org/apache/jackrabbit/core/version/CheckinCalendarTest.java
===================================================================
--- src/test/java/org/apache/jackrabbit/core/version/CheckinCalendarTest.java	(revision 0)
+++ src/test/java/org/apache/jackrabbit/core/version/CheckinCalendarTest.java	(revision 0)
@@ -0,0 +1,42 @@
+/*
+ * 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.jackrabbit.core.version;
+
+import java.util.Calendar;
+
+import javax.jcr.Node;
+import javax.jcr.version.Version;
+
+import org.apache.jackrabbit.core.NodeImpl;
+import org.apache.jackrabbit.test.AbstractJCRTest;
+
+/**
+ * Test case for JCR-1972
+ */
+public class CheckinCalendarTest extends AbstractJCRTest {
+
+	public void testCheckinCalendar() throws Exception {
+		Node n = testRootNode.addNode(nodeName1);
+		n.addMixin(mixVersionable);
+		testRootNode.save();
+		Calendar cal = Calendar.getInstance();
+		cal.set(1971, 4, 6);
+		Version v = ((NodeImpl) n).checkin(cal);
+		assertEquals("Node version creation date should be: " + cal.getTime()
+				+ " and not " + v.getCreated().getTime(), cal, v.getCreated());
+	}
+}
Index: src/test/java/org/apache/jackrabbit/core/version/TestAll.java
===================================================================
--- src/test/java/org/apache/jackrabbit/core/version/TestAll.java	(revision 793403)
+++ src/test/java/org/apache/jackrabbit/core/version/TestAll.java	(working copy)
@@ -37,6 +37,7 @@
         suite.addTestSuite(RemoveVersionLabelTest.class);
         suite.addTestSuite(RestoreTest.class);
         suite.addTestSuite(VersionIteratorImplTest.class);
+        suite.addTestSuite(CheckinCalendarTest.class);
         return suite;
     }
 }
