()
       {
           public Void execute() throws Throwable
           {
               // Check that the version label is correct
               assertEquals("1.2", NODE_SERVICE.getProperty(testNode, ContentModel.PROP_VERSION_LABEL));
               
               // Check that the content is correct
               ContentReader contentReader = CONTENT_SERVICE.getReader(testNode, ContentModel.PROP_CONTENT);
               assertNotNull(contentReader);
               assertEquals(originalContent, contentReader.getContentString());
               
               // Check the history still has 3 versions
               // The head version is now 1.2
               VersionHistory history = VERSION_SERVICE.getVersionHistory(testNode);
               log.debug("Node version history: " + history);
               for (Version v : history.getAllVersions()) { log.debug(v.getVersionLabel()); }
               
               final Version version1_2 = history.getHeadVersion();
               
               assertEquals(version1_2.getVersionLabel(), history.getHeadVersion().getVersionLabel());
               assertEquals(version1_2.getVersionedNodeRef(), history.getHeadVersion().getVersionedNodeRef());
               assertEquals(3, history.getAllVersions().size());
               
               Version[] versions = history.getAllVersions().toArray(new Version[0]);
               assertEquals("1.2", versions[0].getVersionLabel());
               assertEquals("1.1", versions[1].getVersionLabel());
               assertEquals("1.0", versions[2].getVersionLabel());
               
               assertEquals("1.2", history.getHeadVersion().getVersionLabel());
               return null;
           }
       });
    }
    /**
     * MNT-9369
     * 
     * Initially the ContentModel.PROP_AUTO_VERSION and ContentModel.PROP_AUTO_VERSION_PROPS are true by defaults.
     */
    @Test
    public void testVersioningPropsDefault()
    {
        createTestContent(false);
        Map versionableProps = DICTIONARY_SERVICE.getAspect(ContentModel.ASPECT_VERSIONABLE).getProperties();
        autoVersion = Boolean.parseBoolean(versionableProps.get(ContentModel.PROP_AUTO_VERSION).getDefaultValue());
        autoVersionProps = Boolean.parseBoolean(versionableProps.get(ContentModel.PROP_AUTO_VERSION_PROPS).getDefaultValue());
        TRANSACTION_HELPER.doInTransaction(new RetryingTransactionCallback()
        {
            public Void execute() throws Throwable
            {
                log.debug("Adding versionable aspect.");
                ScriptNode sn = new ScriptNode(testNode, SERVICE_REGISTRY);
                sn.addAspect("cm:versionable");
                return null;
            }
        });
        assertEquals("Incorrect Auto Version property.", autoVersion, NODE_SERVICE.getProperty(testNode, ContentModel.PROP_AUTO_VERSION));
        assertEquals("Incorrect Auto Version Props property.", autoVersionProps, NODE_SERVICE.getProperty(testNode, ContentModel.PROP_AUTO_VERSION_PROPS));
    }
    /**
     * MNT-9369
     * 
     * Initially the ContentModel.PROP_AUTO_VERSION and ContentModel.PROP_AUTO_VERSION_PROPS are true by defaults. We'll set them to false.
     */
    @Test
    public void testVersioningPropsDefaultChanged()
    {
        setUpBootstrap();
        TRANSACTION_HELPER.doInTransaction(new RetryingTransactionCallback()
        {
            public Void execute() throws Throwable
            {
                log.debug("Adding new model.");
                // Create a model node
                PropertyMap properties = new PropertyMap(1);
                properties.put(ContentModel.PROP_MODEL_ACTIVE, true);
                final NodeRef modelNode = NODE_SERVICE.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(NamespaceService.ALFRESCO_URI, "dictionaryModels"),
                        ContentModel.TYPE_DICTIONARY_MODEL, properties).getChildRef();
                assertNotNull(modelNode);
                // Add the model content to the model node
                ContentWriter contentWriter = CONTENT_SERVICE.getWriter(modelNode, ContentModel.PROP_CONTENT, true);
                contentWriter.setEncoding("UTF-8");
                contentWriter.setMimetype(MimetypeMap.MIMETYPE_XML);
                InputStream cmStream = getClass().getClassLoader().getResourceAsStream(TEST_CONTENT_MODEL);
                contentWriter.putContent(IOUtils.toString(cmStream));
                cmStream.close();
                return null;
            }
        });
        Map versionableProps = DICTIONARY_SERVICE.getAspect(ContentModel.ASPECT_VERSIONABLE).getProperties();
        autoVersion = Boolean.parseBoolean(versionableProps.get(ContentModel.PROP_AUTO_VERSION).getDefaultValue());
        autoVersionProps = Boolean.parseBoolean(versionableProps.get(ContentModel.PROP_AUTO_VERSION_PROPS).getDefaultValue());
        createTestContent(false);
        TRANSACTION_HELPER.doInTransaction(new RetryingTransactionCallback()
        {
            public Void execute() throws Throwable
            {
                log.debug("Adding versionable aspect.");
                ScriptNode sn = new ScriptNode(testNode, SERVICE_REGISTRY);
                sn.addAspect("cm:versionable");
                return null;
            }
        });
        assertEquals("Incorrect Auto Version property.", autoVersion, NODE_SERVICE.getProperty(testNode, ContentModel.PROP_AUTO_VERSION));
        assertEquals("Incorrect Auto Version Props property.", autoVersionProps, NODE_SERVICE.getProperty(testNode, ContentModel.PROP_AUTO_VERSION_PROPS));
        revertBootstrap();
    }
    
    /**
     * MNT-15798 - Content Data should be created only when it has a binary, not as a side effect of getters on ScriptNode.
     */
    @Test
    public void testContentDataCreation()
    {
        Repository repositoryHelper = (Repository) APP_CONTEXT_INIT.getApplicationContext().getBean("repositoryHelper");
        NodeRef companyHome = repositoryHelper.getCompanyHome();
        NodeRef newNode1 = testNodes.createNode(companyHome, "theTestContent1", ContentModel.TYPE_CONTENT, AuthenticationUtil.getFullyAuthenticatedUser()); 
        // test on content data
        ScriptNode sn = new ScriptNode(newNode1, SERVICE_REGISTRY);
        sn.setScope(getScope());
        ContentData contentData = (ContentData) NODE_SERVICE.getProperty(newNode1, ContentModel.PROP_CONTENT);
        assertNull(contentData);
        sn.setMimetype(MimetypeMap.MIMETYPE_PDF);
        sn.save();
        contentData = (ContentData) NODE_SERVICE.getProperty(newNode1, ContentModel.PROP_CONTENT);
        assertNull(contentData);
        sn.setContent("Marks to prove it.");
        sn.save();
        contentData = (ContentData) NODE_SERVICE.getProperty(newNode1, ContentModel.PROP_CONTENT);
        assertNotNull(contentData);
        assertEquals(true, ContentData.hasContent(contentData));
        // test on ScriptContentData
        NodeRef newNode2 = testNodes.createNode(companyHome, "theTestContent2.txt", ContentModel.TYPE_CONTENT, AuthenticationUtil.getFullyAuthenticatedUser()); 
        ScriptNode sn2 = new ScriptNode(newNode2, SERVICE_REGISTRY);
        sn2.setScope(getScope());
        ScriptContentData scd = sn2.new ScriptContentData(null, ContentModel.PROP_CONTENT);
        //set the "mocked" script content data on the script node
        sn2.getProperties().put(ContentModel.PROP_CONTENT.toString(), scd);
        
        assertEquals(false, scd.isDirty());
        scd.guessMimetype("theTestContent2.pdf");
        assertEquals(false, scd.isDirty());
        scd.setMimetype("text/plain");
        assertEquals(false, scd.isDirty());
        
        scd.setEncoding("UTF-8");
        assertEquals(false, scd.isDirty());
        
        sn2.save();
        contentData = (ContentData) NODE_SERVICE.getProperty(newNode2, ContentModel.PROP_CONTENT);
        assertNull(contentData);
        
        scd.setContent("Marks to prove it.");
        assertEquals(true, scd.isDirty());
        scd.setEncoding("ISO-8859-1");
        assertEquals(true, scd.isDirty());
        
        sn2.save();
        contentData = (ContentData) NODE_SERVICE.getProperty(newNode2, ContentModel.PROP_CONTENT);
        assertNotNull(contentData);
        
        NODE_SERVICE.removeProperty(newNode1, ContentModel.PROP_CONTENT);
        NODE_SERVICE.removeProperty(newNode2, ContentModel.PROP_CONTENT);
    }
    private ScriptableObject getScope() 
    {
        // Create a scope for the value conversion. This scope will be an empty scope exposing basic Object and Function, sufficient for value-conversion.
        // In case no context is active for the current thread, we can safely enter end exit one to get hold of a scope
        ScriptableObject scope;
        Context ctx = Context.getCurrentContext();
        boolean closeContext = false;
        if (ctx == null) 
        {
            ctx = Context.enter();
            closeContext = true;
        }
        scope = ctx.initStandardObjects();
        scope.setParentScope(null);
        if (closeContext) 
        {
            Context.exit();
        }
        return scope;
    }
}