private NodeRef createFolderWithPermission(NodeRef parent, String username, String permission) {
    // Authenticate as system user because the current user should not be node owner
    AuthenticationComponent authenticationComponent =
        (AuthenticationComponent) this.applicationContext.getBean("authenticationComponent");
    authenticationComponent.setSystemUserAsCurrentUser();

    // Create the folder
    NodeRef folder =
        nodeService
            .createNode(
                parent,
                ContentModel.ASSOC_CHILDREN,
                QName.createQName("TestFolder" + GUID.generate()),
                ContentModel.TYPE_CONTENT)
            .getChildRef();

    // Apply permissions to folder
    permissionService.deletePermissions(folder);
    permissionService.setInheritParentPermissions(folder, false);
    permissionService.setPermission(folder, userName, permission, true);

    // Authenticate test user
    TestWithUserUtils.authenticateUser(
        this.userName, PWD, this.rootNodeRef, this.authenticationService);

    return folder;
  }
  public void testCheckOutCheckInWithTranslatableAspect() {
    // Create a node to be used as the translation
    NodeRef translationNodeRef =
        nodeService
            .createNode(
                rootNodeRef,
                ContentModel.ASSOC_CHILDREN,
                QName.createQName("translation"),
                ContentModel.TYPE_CONTENT)
            .getChildRef();

    nodeService.addAspect(
        this.nodeRef,
        QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "translatable"),
        null);
    nodeService.createAssociation(
        this.nodeRef,
        translationNodeRef,
        QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "translations"));

    // Check it out
    NodeRef workingCopy =
        cociService.checkout(
            this.nodeRef,
            this.rootNodeRef,
            ContentModel.ASSOC_CHILDREN,
            QName.createQName("workingCopy"));

    // Check it back in again
    Map<String, Serializable> versionProperties = new HashMap<String, Serializable>();
    versionProperties.put(Version.PROP_DESCRIPTION, "This is a test version");
    cociService.checkin(workingCopy, versionProperties);
  }
  /**
   * @see CheckOutCheckInService#getWorkingCopy(NodeRef)
   * @see CheckOutCheckInService#getCheckedOut(NodeRef)
   */
  public void testBidirectionalReferences() {
    final NodeRef origNodeRef =
        nodeService
            .createNode(
                this.rootNodeRef,
                ContentModel.ASSOC_CHILDREN,
                QName.createQName("test2"),
                ContentModel.TYPE_CONTENT)
            .getChildRef();

    NodeRef wk1 = cociService.getWorkingCopy(origNodeRef);
    assertNull(wk1);

    // Check the document out
    final NodeRef workingCopy = cociService.checkout(origNodeRef);
    assertTrue(
        "Expect cm:workingcopy aspect",
        nodeService.hasAspect(workingCopy, ContentModel.ASPECT_WORKING_COPY));
    assertTrue(
        "Expect cm:checkedOut aspect",
        nodeService.hasAspect(origNodeRef, ContentModel.ASPECT_CHECKED_OUT));
    List<AssociationRef> targetAssocs =
        nodeService.getTargetAssocs(origNodeRef, ContentModel.ASSOC_WORKING_COPY_LINK);
    assertEquals("Expect a 1:1 relationship", 1, targetAssocs.size());
    List<AssociationRef> sourceAssocs =
        nodeService.getSourceAssocs(workingCopy, ContentModel.ASSOC_WORKING_COPY_LINK);
    assertEquals("Expect a 1:1 relationship", 1, sourceAssocs.size());

    // Need to commit the transaction in order to get the indexer to run
    setComplete();
    endTransaction();

    final NodeRef finalNodeRef = origNodeRef;

    this.transactionService
        .getRetryingTransactionHelper()
        .doInTransaction(
            new RetryingTransactionCallback<Object>() {
              public Object execute() {
                NodeRef wk2 = cociService.getWorkingCopy(finalNodeRef);
                assertNotNull(wk2);
                assertEquals(workingCopy, wk2);
                NodeRef orig2 = cociService.getCheckedOut(wk2);
                assertNotNull(orig2);
                assertEquals(origNodeRef, orig2);

                cociService.cancelCheckout(workingCopy);
                return null;
              }
            });

    NodeRef wk3 = cociService.getWorkingCopy(this.nodeRef);
    assertNull(wk3);
  }
  /** Test the getWorkingCopy method */
  public void testETWOTWO_733() {
    NodeRef origNodeRef =
        nodeService
            .createNode(
                this.rootNodeRef,
                ContentModel.ASSOC_CHILDREN,
                QName.createQName("test2"),
                ContentModel.TYPE_CONTENT)
            .getChildRef();

    // Make a copy of the node
    this.copyService.copyAndRename(
        origNodeRef,
        this.rootNodeRef,
        ContentModel.ASSOC_CHILDREN,
        QName.createQName("test6"),
        false);

    NodeRef wk1 = cociService.getWorkingCopy(origNodeRef);
    assertNull(wk1);

    // Check the document out
    final NodeRef workingCopy = cociService.checkout(origNodeRef);

    // Need to commit the transaction in order to get the indexer to run
    setComplete();
    endTransaction();

    final NodeRef finalNodeRef = origNodeRef;

    this.transactionService
        .getRetryingTransactionHelper()
        .doInTransaction(
            new RetryingTransactionCallback<Object>() {
              public Object execute() {
                NodeRef wk2 = cociService.getWorkingCopy(finalNodeRef);
                assertNotNull(wk2);
                assertEquals(workingCopy, wk2);

                cociService.cancelCheckout(workingCopy);
                return null;
              }
            });

    NodeRef wk3 = cociService.getWorkingCopy(this.nodeRef);
    assertNull(wk3);
  }
  /** Ensure that the node has a <b>fm:forum</b> child node otherwise create one */
  public void onAddAspect(NodeRef discussableNodeRef, QName aspectTypeQName) {
    String name = (String) this.nodeService.getProperty(discussableNodeRef, ContentModel.PROP_NAME);
    String forumName = I18NUtil.getMessage("discussion.discussion_for", new Object[] {name});

    NodeRef forumNodeRef = getForum(discussableNodeRef);

    if (forumNodeRef == null) {
      Map<QName, Serializable> forumProps = new HashMap<QName, Serializable>(1);
      forumProps.put(ContentModel.PROP_NAME, forumName);

      ChildAssociationRef childRef =
          nodeService.createNode(
              discussableNodeRef,
              ForumModel.ASSOC_DISCUSSION,
              QName.createQName(NamespaceService.FORUMS_MODEL_1_0_URI, "discussion"),
              ForumModel.TYPE_FORUM,
              forumProps);

      forumNodeRef = childRef.getChildRef();
    } else {
      // Just adjust the name
      nodeService.setProperty(forumNodeRef, ContentModel.PROP_NAME, forumName);
    }

    // apply the uifacets aspect
    Map<QName, Serializable> uiFacetsProps = new HashMap<QName, Serializable>(5);
    uiFacetsProps.put(ApplicationModel.PROP_ICON, "forum");
    this.nodeService.addAspect(forumNodeRef, ApplicationModel.ASPECT_UIFACETS, uiFacetsProps);

    // Done
    if (logger.isDebugEnabled()) {
      logger.debug(
          "Created forum node for discussion: \n"
              + "   Discussable Node: "
              + discussableNodeRef
              + "\n"
              + "   Forum Node:       "
              + forumNodeRef);
    }
  }
  public NodeRef createDownloadNode(boolean recursive) {
    NodeRef downloadsContainer = getOrCreateDowloadContainer();

    Map<QName, Serializable> downloadProperties = new HashMap<QName, Serializable>();
    downloadProperties.put(DownloadModel.PROP_RECURSIVE, recursive);

    ChildAssociationRef newChildAssoc =
        nodeService.createNode(
            downloadsContainer,
            ContentModel.ASSOC_CHILDREN,
            ContentModel.ASSOC_CHILDREN,
            DownloadModel.TYPE_DOWNLOAD,
            downloadProperties);

    final NodeRef downloadNodeRef = newChildAssoc.getChildRef();

    if (log.isDebugEnabled()) {
      StringBuilder msg = new StringBuilder();
      msg.append("Created Download. ").append("', Download-NodeRef=");
      log.debug(msg.toString());
    }
    return downloadNodeRef;
  }
  /** Test when the aspect is not set when check-in is performed */
  public void testVersionAspectNotSetOnCheckIn() {
    // Create a bag of props
    Map<QName, Serializable> bagOfProps = createTypePropertyBag();
    bagOfProps.put(
        ContentModel.PROP_CONTENT,
        new ContentData(null, MimetypeMap.MIMETYPE_TEXT_PLAIN, 0L, "UTF-8"));

    // Create a new node
    ChildAssociationRef childAssocRef =
        nodeService.createNode(
            rootNodeRef,
            ContentModel.ASSOC_CHILDREN,
            QName.createQName("test"),
            ContentModel.TYPE_CONTENT,
            bagOfProps);
    NodeRef noVersionNodeRef = childAssocRef.getChildRef();

    // Check out and check in
    NodeRef workingCopy = cociService.checkout(noVersionNodeRef);
    cociService.checkin(workingCopy, new HashMap<String, Serializable>());

    // Check that the origional node has no version history dispite sending verion props
    assertNull(this.versionService.getVersionHistory(noVersionNodeRef));
  }
  /**
   * Write exception transfer report
   *
   * @return NodeRef the node ref of the new transfer report
   */
  public NodeRef createTransferReport(
      Exception e,
      TransferTarget target,
      TransferDefinition definition,
      List<TransferEvent> events,
      File snapshotFile) {
    Map<QName, Serializable> properties = new HashMap<QName, Serializable>();

    SimpleDateFormat format = new SimpleDateFormat("yyyyMMddhhmmssSSSZ");
    String timeNow = format.format(new Date());

    String title = "Transfer report, error,  " + timeNow;
    String description = "Transfer error report";
    String name = "Transfer error report, " + timeNow;

    properties.put(ContentModel.PROP_NAME, name);
    properties.put(ContentModel.PROP_TITLE, title);
    properties.put(ContentModel.PROP_DESCRIPTION, description);
    ChildAssociationRef ref =
        nodeService.createNode(
            target.getNodeRef(),
            ContentModel.ASSOC_CONTAINS,
            QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name),
            TransferModel.TYPE_TRANSFER_REPORT,
            properties);
    ContentWriter writer =
        contentService.getWriter(ref.getChildRef(), ContentModel.PROP_CONTENT, true);
    writer.setLocale(Locale.getDefault());
    writer.setMimetype(MimetypeMap.MIMETYPE_XML);
    writer.setEncoding(DEFAULT_ENCODING);

    //
    XMLTransferReportWriter reportWriter = new XMLTransferReportWriter();

    BufferedWriter bufferedWriter =
        new BufferedWriter(new OutputStreamWriter(writer.getContentOutputStream()));

    try {
      reportWriter.startTransferReport(DEFAULT_ENCODING, bufferedWriter);

      // Header
      reportWriter.writeTarget(target);

      reportWriter.writeDefinition(definition);

      reportWriter.writeException(e);

      // Detail
      reportWriter.writeTransferEvents(events);

      reportWriter.endTransferReport();

      return ref.getChildRef();
    } catch (SAXException se) {
      return null;
    } finally {
      try {
        bufferedWriter.close();
      } catch (IOException error) {
        error.printStackTrace();
      }
    }
  }
  /**
   * Create a new transfer report of success
   *
   * @return NodeRef the node ref of the new transfer report
   */
  public NodeRef createTransferReport(
      Transfer transfer,
      TransferTarget target,
      TransferDefinition definition,
      List<TransferEvent> events,
      File snapshotFile) {
    Map<QName, Serializable> properties = new HashMap<QName, Serializable>();

    SimpleDateFormat format = new SimpleDateFormat("yyyyMMddhhmmssSSSZ");
    String timeNow = format.format(new Date());

    String title = "Transfer report, " + timeNow + "success";
    String description = "Transfer report success targetName : " + target.getName();
    String name = "Transfer report, " + timeNow;

    properties.put(ContentModel.PROP_NAME, name);
    properties.put(ContentModel.PROP_TITLE, title);
    properties.put(ContentModel.PROP_DESCRIPTION, description);
    ChildAssociationRef ref =
        nodeService.createNode(
            target.getNodeRef(),
            ContentModel.ASSOC_CONTAINS,
            QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name),
            TransferModel.TYPE_TRANSFER_REPORT,
            properties);
    ContentWriter writer =
        contentService.getWriter(ref.getChildRef(), ContentModel.PROP_CONTENT, true);
    writer.setLocale(Locale.getDefault());
    writer.setMimetype(MimetypeMap.MIMETYPE_XML);
    writer.setEncoding(DEFAULT_ENCODING);

    //
    final XMLTransferReportWriter reportWriter = new XMLTransferReportWriter();

    BufferedWriter bufferedWriter =
        new BufferedWriter(new OutputStreamWriter(writer.getContentOutputStream()));

    try {
      reportWriter.startTransferReport(DEFAULT_ENCODING, bufferedWriter);

      // Header
      reportWriter.writeTarget(target);

      reportWriter.writeDefinition(definition);

      /** Write the node summary details to the transfer report */
      TransferManifestProcessor processor =
          new TransferManifestProcessor() {
            public void processTransferManifestNode(TransferManifestNormalNode node) {

              try {
                reportWriter.writeNodeSummary(node);
              } catch (SAXException error) {
                error.printStackTrace();
              }
            }

            public void processTransferManifestNode(TransferManifestDeletedNode node) {
              try {
                reportWriter.writeNodeSummary(node);
              } catch (SAXException error) {
                error.printStackTrace();
              }
            }

            public void processTransferManifiestHeader(TransferManifestHeader header) {
              /* NO-OP */
            }

            public void startTransferManifest() {
              /* NO-OP */
            }

            public void endTransferManifest() {
              /* NO-OP */
            }
          };

      /** Step 3: wire up the manifest reader to a manifest processor */
      SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
      SAXParser parser;
      parser = saxParserFactory.newSAXParser();
      XMLTransferManifestReader reader = new XMLTransferManifestReader(processor);

      /** Step 4: start the magic Give the manifest file to the manifest reader */
      try {
        parser.parse(snapshotFile, reader);
      } catch (IOException error) {
        // TODO temp code
        error.printStackTrace();
        return null;
      }

      // Detail Events
      reportWriter.writeTransferEvents(events);

      reportWriter.endTransferReport();

      return ref.getChildRef();
    } catch (SAXException se) {
      // TODO Temp code
      return null;
    } catch (ParserConfigurationException error) {
      // TODO temp code
      error.printStackTrace();
      return null;
    } finally {
      try {
        bufferedWriter.close();
      } catch (IOException error) {
        error.printStackTrace();
      }
    }
  }
  public void setUp() throws Exception {
    if (AlfrescoTransactionSupport.getTransactionReadState() != TxnReadState.TXN_NONE) {
      throw new AlfrescoRuntimeException(
          "A previous tests did not clean up transaction: "
              + AlfrescoTransactionSupport.getTransactionId());
    }

    nodeService = (NodeService) applicationContext.getBean("nodeService");
    dictionaryService =
        (DictionaryService)
            applicationContext.getBean(ServiceRegistry.DICTIONARY_SERVICE.getLocalName());
    permissionService = (PermissionServiceSPI) applicationContext.getBean("permissionService");
    permissionServiceImpl =
        (PermissionServiceImpl) applicationContext.getBean("permissionServiceImpl");
    namespacePrefixResolver =
        (NamespacePrefixResolver)
            applicationContext.getBean(ServiceRegistry.NAMESPACE_SERVICE.getLocalName());
    authenticationService =
        (MutableAuthenticationService) applicationContext.getBean("authenticationService");
    authenticationComponent =
        (AuthenticationComponent) applicationContext.getBean("authenticationComponent");
    serviceRegistry =
        (ServiceRegistry) applicationContext.getBean(ServiceRegistry.SERVICE_REGISTRY);
    permissionModelDAO = (ModelDAO) applicationContext.getBean("permissionsModelDAO");
    personService = (PersonService) applicationContext.getBean("personService");
    authorityService = (AuthorityService) applicationContext.getBean("authorityService");
    authorityDAO = (AuthorityDAO) applicationContext.getBean("authorityDAO");

    authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName());
    authenticationDAO = (MutableAuthenticationDao) applicationContext.getBean("authenticationDao");
    nodeDAO = (NodeDAO) applicationContext.getBean("nodeDAO");
    aclDaoComponent = (AclDAO) applicationContext.getBean("aclDAO");

    publicServiceAccessService =
        (PublicServiceAccessService) applicationContext.getBean("publicServiceAccessService");

    retryingTransactionHelper =
        (RetryingTransactionHelper) applicationContext.getBean("retryingTransactionHelper");

    transactionService = (TransactionService) applicationContext.getBean("transactionComponent");

    testTX = transactionService.getUserTransaction();
    testTX.begin();

    testStoreRef =
        nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "Test_" + System.nanoTime());
    rootNodeRef = nodeService.getRootNode(testStoreRef);

    QName children = ContentModel.ASSOC_CHILDREN;
    QName system = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "system");
    QName container = ContentModel.TYPE_CONTAINER;
    QName types = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "people");

    systemNodeRef = nodeService.createNode(rootNodeRef, children, system, container).getChildRef();
    NodeRef typesNodeRef =
        nodeService.createNode(systemNodeRef, children, types, container).getChildRef();
    Map<QName, Serializable> props = createPersonProperties("andy");
    nodeService
        .createNode(typesNodeRef, children, ContentModel.TYPE_PERSON, container, props)
        .getChildRef();
    props = createPersonProperties("lemur");
    nodeService
        .createNode(typesNodeRef, children, ContentModel.TYPE_PERSON, container, props)
        .getChildRef();

    // create an authentication object e.g. the user
    if (authenticationDAO.userExists("andy")) {
      authenticationService.deleteAuthentication("andy");
    }
    authenticationService.createAuthentication("andy", "andy".toCharArray());

    if (authenticationDAO.userExists("lemur")) {
      authenticationService.deleteAuthentication("lemur");
    }
    authenticationService.createAuthentication("lemur", "lemur".toCharArray());

    if (authenticationDAO.userExists(AuthenticationUtil.getAdminUserName())) {
      authenticationService.deleteAuthentication(AuthenticationUtil.getAdminUserName());
    }
    authenticationService.createAuthentication(
        AuthenticationUtil.getAdminUserName(), "admin".toCharArray());

    authenticationComponent.clearCurrentSecurityContext();

    assertTrue(permissionServiceImpl.getAnyDenyDenies());
  }
  /** Test for MNT-11725 */
  public void testDowngradePermissions() throws Exception {
    NodeRef rootNodeRef = this.nodeService.getRootNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
    NodeRef folderRef =
        nodeService
            .createNode(
                rootNodeRef,
                ContentModel.ASSOC_CHILDREN,
                QName.createQName(NamespaceService.ALFRESCO_URI, "testFolder"),
                ContentModel.TYPE_FOLDER)
            .getChildRef();
    permissionService.setPermission(folderRef, USER_ONE, PermissionService.COORDINATOR, true);
    permissionService.setInheritParentPermissions(folderRef, false);

    authenticationComponent.setCurrentUser(USER_ONE);

    // JSON fromat
    //  {"permissions":
    //  [{"authority":"userA",
    //  "role":"Consumer"},
    //  {"authority":"userA",
    //  "role":"Coordinator",
    //  "remove":true}],
    //  "isInherited":true}

    /*  negative test, we are first deleting the coordinator role and then try to add consumer */
    JSONObject changePermission = new JSONObject();
    JSONArray permissions = new JSONArray();
    // First delete permission, then add
    JSONObject addPermission = new JSONObject();
    addPermission.put("authority", USER_ONE);
    addPermission.put("role", PermissionService.CONSUMER);
    JSONObject removePermission = new JSONObject();
    removePermission.put("authority", USER_ONE);
    removePermission.put("role", PermissionService.COORDINATOR);
    removePermission.put("remove", "true");
    permissions.put(removePermission);
    permissions.put(addPermission);
    changePermission.put("permissions", permissions);
    changePermission.put("isInherited", "true");

    sendRequest(
        new PostRequest(
            URL_DOCLIB_PERMISSIONS
                + "/"
                + StoreRef.STORE_REF_WORKSPACE_SPACESSTORE.getProtocol()
                + "/"
                + StoreRef.STORE_REF_WORKSPACE_SPACESSTORE.getIdentifier()
                + "/"
                + folderRef.getId(),
            changePermission.toString(),
            "application/json"),
        Status.STATUS_INTERNAL_SERVER_ERROR);

    /*  positive test  */
    changePermission = new JSONObject();
    permissions = new JSONArray();
    // First add permission, then delete
    addPermission = new JSONObject();
    addPermission.put("authority", USER_ONE);
    addPermission.put("role", PermissionService.CONSUMER);
    removePermission = new JSONObject();
    removePermission.put("authority", USER_ONE);
    removePermission.put("role", PermissionService.COORDINATOR);
    removePermission.put("remove", "true");
    permissions.put(addPermission);
    permissions.put(removePermission);
    changePermission.put("permissions", permissions);
    changePermission.put("isInherited", "true");

    sendRequest(
        new PostRequest(
            URL_DOCLIB_PERMISSIONS
                + "/"
                + StoreRef.STORE_REF_WORKSPACE_SPACESSTORE.getProtocol()
                + "/"
                + StoreRef.STORE_REF_WORKSPACE_SPACESSTORE.getIdentifier()
                + "/"
                + folderRef.getId(),
            changePermission.toString(),
            "application/json"),
        Status.STATUS_OK);

    AccessStatus accessStatus =
        permissionService.hasPermission(folderRef, PermissionService.CONSUMER);
    assertTrue("The permission was not set correctly", accessStatus == AccessStatus.ALLOWED);

    this.authenticationComponent.setCurrentUser(AuthenticationUtil.getAdminUserName());
    nodeService.deleteNode(folderRef);
  }
  public void testMultipleCheckoutsCheckInsWithPropChange() {
    // Note: this test assumes cm:autoVersionProps=true by default (refer to cm:versionableAspect in
    // contentModel.xml)

    // Create a new node
    ChildAssociationRef childAssocRef =
        nodeService.createNode(
            rootNodeRef,
            ContentModel.ASSOC_CHILDREN,
            QName.createQName("test"),
            ContentModel.TYPE_CONTENT,
            null);
    final NodeRef testNodeRef = childAssocRef.getChildRef();

    // Add the version aspect to the created node
    nodeService.addAspect(testNodeRef, ContentModel.ASPECT_VERSIONABLE, null);

    setComplete();
    endTransaction();

    // Checkout
    final NodeRef workingCopy1 =
        transactionService
            .getRetryingTransactionHelper()
            .doInTransaction(
                new RetryingTransactionCallback<NodeRef>() {
                  public NodeRef execute() throws Exception {
                    return cociService.checkout(testNodeRef);
                  }
                });

    // Change property and checkin
    transactionService
        .getRetryingTransactionHelper()
        .doInTransaction(
            new RetryingTransactionCallback<Object>() {
              public Object execute() throws Exception {
                nodeService.setProperty(workingCopy1, ContentModel.PROP_AUTHOR, "author1");

                Map<String, Serializable> versionProperties = new HashMap<String, Serializable>();
                versionProperties.put(Version.PROP_DESCRIPTION, "This is a test version 1");
                cociService.checkin(workingCopy1, versionProperties);

                return null;
              }
            });

    // Checkout
    final NodeRef workingCopy2 =
        transactionService
            .getRetryingTransactionHelper()
            .doInTransaction(
                new RetryingTransactionCallback<NodeRef>() {
                  public NodeRef execute() throws Exception {
                    return cociService.checkout(testNodeRef);
                  }
                });

    // Change property and checkin
    transactionService
        .getRetryingTransactionHelper()
        .doInTransaction(
            new RetryingTransactionCallback<Object>() {
              public Object execute() throws Exception {
                nodeService.setProperty(workingCopy2, ContentModel.PROP_AUTHOR, "author2");

                Map<String, Serializable> versionProperties = new HashMap<String, Serializable>();
                versionProperties.put(Version.PROP_DESCRIPTION, "This is a test version 2");
                cociService.checkin(workingCopy2, versionProperties);

                return null;
              }
            });

    // Checkout
    final NodeRef workingCopy3 =
        transactionService
            .getRetryingTransactionHelper()
            .doInTransaction(
                new RetryingTransactionCallback<NodeRef>() {
                  public NodeRef execute() throws Exception {
                    return cociService.checkout(testNodeRef);
                  }
                });

    // Change property and checkin
    transactionService
        .getRetryingTransactionHelper()
        .doInTransaction(
            new RetryingTransactionCallback<Object>() {
              public Object execute() throws Exception {
                nodeService.setProperty(workingCopy3, ContentModel.PROP_AUTHOR, "author3");

                Map<String, Serializable> versionProperties = new HashMap<String, Serializable>();
                versionProperties.put(Version.PROP_DESCRIPTION, "This is a test version 3");
                cociService.checkin(workingCopy3, versionProperties);

                return null;
              }
            });
  }
  /** On setup in transaction implementation */
  @Override
  protected void onSetUpInTransaction() throws Exception {
    // Set the services
    this.nodeService = (NodeService) this.applicationContext.getBean("nodeService");
    this.cociService =
        (CheckOutCheckInService) this.applicationContext.getBean("checkOutCheckInService");
    this.contentService = (ContentService) this.applicationContext.getBean("contentService");
    this.versionService = (VersionService) this.applicationContext.getBean("versionService");
    this.authenticationService =
        (MutableAuthenticationService) this.applicationContext.getBean("authenticationService");
    this.lockService = (LockService) this.applicationContext.getBean("lockService");
    this.transactionService =
        (TransactionService) this.applicationContext.getBean("transactionComponent");
    this.permissionService =
        (PermissionService) this.applicationContext.getBean("permissionService");
    this.copyService = (CopyService) this.applicationContext.getBean("copyService");

    // Authenticate as system to create initial test data set
    AuthenticationComponent authenticationComponent =
        (AuthenticationComponent) this.applicationContext.getBean("authenticationComponent");
    authenticationComponent.setSystemUserAsCurrentUser();

    // Create the store and get the root node reference
    this.storeRef =
        nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "Test_" + System.currentTimeMillis());
    this.rootNodeRef = nodeService.getRootNode(storeRef);

    // Create the node used for tests
    ChildAssociationRef childAssocRef =
        nodeService.createNode(
            rootNodeRef,
            ContentModel.ASSOC_CHILDREN,
            QName.createQName("test"),
            ContentModel.TYPE_CONTENT);
    this.nodeRef = childAssocRef.getChildRef();
    nodeService.addAspect(this.nodeRef, ContentModel.ASPECT_TITLED, null);
    nodeService.setProperty(this.nodeRef, ContentModel.PROP_NAME, TEST_VALUE_NAME);
    nodeService.setProperty(this.nodeRef, PROP2_QNAME, TEST_VALUE_2);

    // Add the initial content to the node
    ContentWriter contentWriter =
        this.contentService.getWriter(this.nodeRef, ContentModel.PROP_CONTENT, true);
    contentWriter.setMimetype("text/plain");
    contentWriter.setEncoding("UTF-8");
    contentWriter.putContent(CONTENT_1);

    // Add the lock and version aspects to the created node
    nodeService.addAspect(this.nodeRef, ContentModel.ASPECT_VERSIONABLE, null);
    nodeService.addAspect(this.nodeRef, ContentModel.ASPECT_LOCKABLE, null);

    // Create and authenticate the user
    this.userName = "******" + GUID.generate();
    TestWithUserUtils.createUser(
        this.userName, PWD, this.rootNodeRef, this.nodeService, this.authenticationService);
    TestWithUserUtils.authenticateUser(
        this.userName, PWD, this.rootNodeRef, this.authenticationService);
    this.userNodeRef = TestWithUserUtils.getCurrentUser(this.authenticationService);

    permissionService.setPermission(
        this.rootNodeRef, this.userName, PermissionService.ALL_PERMISSIONS, true);
    permissionService.setPermission(
        this.nodeRef, this.userName, PermissionService.ALL_PERMISSIONS, true);

    folderNodeRef =
        nodeService
            .createNode(
                rootNodeRef,
                ContentModel.ASSOC_CHILDREN,
                QName.createQName("test"),
                ContentModel.TYPE_FOLDER,
                Collections.<QName, Serializable>singletonMap(ContentModel.PROP_NAME, "folder"))
            .getChildRef();
    fileNodeRef =
        nodeService
            .createNode(
                folderNodeRef,
                ContentModel.ASSOC_CONTAINS,
                QName.createQName("test"),
                ContentModel.TYPE_CONTENT,
                Collections.<QName, Serializable>singletonMap(ContentModel.PROP_NAME, "file"))
            .getChildRef();
    contentWriter = this.contentService.getWriter(fileNodeRef, ContentModel.PROP_CONTENT, true);
    contentWriter.setMimetype("text/plain");
    contentWriter.setEncoding("UTF-8");
    contentWriter.putContent(CONTENT_1);
  }