ReadOnlyVersionManager { @Nullable public Tree getVersionable(@NotNull Tree versionTree, @NotNull String workspaceName) { Root root = getWorkspaceRoot(); String relPath = ""; Tree t = versionTree; while (t.exists() && !isVersionStoreTree(t) && !t.isRoot()) { String ntName = TreeUtil.getPrimaryTypeName(t); if (VersionConstants.NT_FROZENNODE.equals(ntName)) { relPath = PathUtils.relativize(t.getPath(), versionTree.getPath()); } else if (JcrConstants.NT_VERSIONHISTORY.equals(ntName)) { PropertyState prop = t.getProperty(workspaceName); if (prop != null) { return root.getTree(PathUtils.concat(prop.getValue(Type.PATH), relPath)); } else { log.warn("Missing versionable path property for {} at {}", workspaceName, t.getPath()); break; } } t = t.getParent(); } return null; }  @NotNull static ReadOnlyVersionManager getInstance(final Root root,
                                                     final NamePathMapper namePathMapper); boolean isCheckedOut(@NotNull Tree tree); @Nullable Tree getVersionHistory(@NotNull Tree versionable); @Nullable Tree getVersion(@NotNull String uuid); @NotNull String getVersionHistoryPath(@NotNull String uuid); @Nullable Tree getBaseVersion(@NotNull Tree versionable); static boolean isVersionStoreTree(@NotNull Tree tree); @Nullable Tree getVersionable(@NotNull Tree versionTree, @NotNull String workspaceName);  }
@Test public void testGetVersionable() throws Exception { Tree versionHistory = checkNotNull(versionManager.getVersionHistory(root.getTree("/a"))); assertVersionable("/a", versionHistory); Tree rootVersion = versionHistory.getChild(JcrConstants.JCR_ROOTVERSION); assertVersionable("/a", rootVersion); Tree baseVersion = checkNotNull(versionManager.getBaseVersion(versionable)); assertVersionable("/a", baseVersion); Tree frozen = baseVersion.getChild(VersionConstants.JCR_FROZENNODE); assertVersionable("/a", frozen); Tree frozenB = frozen.getChild("b"); assertVersionable("/a/b", frozenB); Tree frozenC = frozenB.getChild("c"); assertVersionable("/a/b/c", frozenC); }