/**
   * {@inheritDoc}
   *
   * @see
   *     org.modeshape.graph.request.processor.RequestProcessor#process(org.modeshape.graph.request.CloneBranchRequest)
   */
  @Override
  public void process(CloneBranchRequest request) {
    if (request == null) return;
    try {
      String fromWorkspaceName = request.fromWorkspace();
      String intoWorkspaceName = request.intoWorkspace();
      boolean sameWorkspace = fromWorkspaceName.equals(intoWorkspaceName);
      Workspace fromWorkspace = workspaceFor(fromWorkspaceName);
      Workspace intoWorkspace = sameWorkspace ? fromWorkspace : workspaceFor(intoWorkspaceName);
      Node sourceNode = fromWorkspace.node(request.from());
      Node targetNode = fromWorkspace.node(request.into());
      Location fromLocation = fromWorkspace.locationFor(sourceNode);

      // Calculate the source and destination paths ...
      String srcAbsPath = sourceNode.getPath();
      String destAbsPath = targetNode.getPath();
      String copyName =
          request.desiredName() != null
              ? intoWorkspace.stringFor(request.desiredName())
              : sourceNode.getName();
      destAbsPath += '/' + copyName;

      // Perform the clone ...
      javax.jcr.Workspace workspace = intoWorkspace.session().getWorkspace();
      workspace.clone(fromWorkspaceName, srcAbsPath, destAbsPath, request.removeExisting());

      // Find the actual location of the result of the node ...
      Node last = null;
      for (NodeIterator iter = targetNode.getNodes(copyName); iter.hasNext(); ) {
        last = iter.nextNode();
      }
      Location intoLocation = intoWorkspace.locationFor(last);
      request.setActualLocations(fromLocation, intoLocation);
    } catch (Throwable e) {
      request.setError(e);
    }
  }