docs: void restore( JcrSession session,
                    Path path,
                    Version version,
                    String labelToRestore,
                    boolean removeExisting ) throws RepositoryException {
  
          // Ensure that the parent node exists - this will throw a PNFE if no node exists at that path
          AbstractJcrNode parentNode = session.node(path.getParent());
          AbstractJcrNode existingNode = null;
          AbstractJcrNode nodeToCheckLock;
  
          JcrVersionNode jcrVersion = (JcrVersionNode)version;
          SessionCache cache = session.cache();
          PropertyFactory propFactory = session.propertyFactory();
  
          try {
              existingNode = parentNode.childNode(path.getLastSegment(), null);
              nodeToCheckLock = existingNode;
  
              // These checks only make sense if there is an existing node
              JcrVersionHistoryNode versionHistory = existingNode.getVersionHistory();
              if (!versionHistory.isSame(jcrVersion.getParent())) {
                  throw new VersionException(JcrI18n.invalidVersion.text(version.getPath(), versionHistory.getPath()));
              }
  
              if (!versionHistory.isSame(existingNode.getVersionHistory())) {
                  throw new VersionException(JcrI18n.invalidVersion.text(version.getPath(), existingNode.getVersionHistory()
                                                                                                        .getPath()));
              }
  
              if (jcrVersion.isSame(versionHistory.getRootVersion())) {
                  throw new VersionException(JcrI18n.cannotRestoreRootVersion.text(existingNode.getPath()));
              }
  
          } catch (PathNotFoundException pnfe) {
              // This is allowable, but the node needs to be checked out
              if (!parentNode.isCheckedOut()) {
                  String parentPath = path.getString(session.context().getNamespaceRegistry());
                  throw new VersionException(JcrI18n.nodeIsCheckedIn.text(parentPath));
              }
  
              AbstractJcrNode sourceNode = session.workspace().getVersionManager().frozenNodeFor(version);
              Name primaryTypeName = session.nameFactory().create(sourceNode.getProperty(JcrLexicon.FROZEN_PRIMARY_TYPE)
                                                                            .property()
                                                                            .getFirstValue());
              AbstractJcrProperty uuidProp = sourceNode.getProperty(JcrLexicon.FROZEN_UUID);
              String frozenUuidString = session.stringFactory().create(uuidProp.property().getFirstValue());
              NodeKey desiredKey = parentNode.key().withId(frozenUuidString);
              Name name = path.getLastSegment().getName();
  
              if (ModeShapeLexicon.SHARE.equals(primaryTypeName)) {
                  // Need to link to the existing node with the identifier ...
                  parentNode.mutable().linkChild(cache, desiredKey, name);
                  existingNode = session.node(desiredKey, (Type)null, parentNode.key());
              } else {
                  // Otherwise recreate/restore the new child ...
                  Property primaryType = propFactory.create(JcrLexicon.PRIMARY_TYPE, primaryTypeName);
                  MutableCachedNode newChild = parentNode.mutable().createChild(cache, desiredKey, name, primaryType);
                  existingNode = session.node(newChild, (Type)null, parentNode.key());
              }
              nodeToCheckLock = parentNode;
          }
  
          // Check whether the node to check is locked
          if (nodeToCheckLock.isLocked() && !nodeToCheckLock.holdsLock()) {
              throw new LockException(JcrI18n.lockTokenNotHeld.text(nodeToCheckLock.getPath()));
          }
  
          RestoreCommand op = new RestoreCommand(session, Collections.singletonMap(jcrVersion, existingNode),
                                                 Collections.singleton(existingNode.path()), Collections.<Version>emptySet(),
                                                 labelToRestore, removeExisting);
          op.execute();
          session.save();
      }