docs: public boolean copyResource( ITransaction transaction,
                                   HttpServletRequest req,
                                   HttpServletResponse resp ) throws WebdavException, IOException, LockFailedException {
  
          // Parsing destination header
          String destinationPath = parseDestinationHeader(req, resp);
  
          if (destinationPath == null) {
              return false;
          }
  
          String path = getRelativePath(req);
  
          if (path.equals(destinationPath)) {
              resp.sendError(WebdavStatus.SC_FORBIDDEN);
              return false;
          }
  
          Hashtable<String, Integer> errorList = new Hashtable<String, Integer>();
          String parentDestinationPath = getParentPath(getCleanPath(destinationPath));
  
          if (!isUnlocked(transaction, req, resourceLocks, parentDestinationPath)) {
              resp.setStatus(WebdavStatus.SC_LOCKED);
              return false; // parentDestination is locked
          }
  
          if (!isUnlocked(transaction, req, resourceLocks, destinationPath)) {
              resp.setStatus(WebdavStatus.SC_LOCKED);
              return false; // destination is locked
          }
  
          // Parsing overwrite header
          boolean overwrite = shouldOverwrite(req);
  
          // Overwriting the destination
          String lockOwner = "copyResource" + System.currentTimeMillis() + req.toString();
  
          if (resourceLocks.lock(transaction, destinationPath, lockOwner, false, 0, TEMP_TIMEOUT, TEMPORARY)) {
              StoredObject copySo, destinationSo = null;
              try {
                  copySo = store.getStoredObject(transaction, path);
                  // Retrieve the resources
                  if (copySo == null) {
                      resp.sendError(HttpServletResponse.SC_NOT_FOUND);
                      return false;
                  }
  
                  if (copySo.isNullResource()) {
                      String methodsAllowed = DeterminableMethod.determineMethodsAllowed(copySo);
                      resp.addHeader("Allow", methodsAllowed);
                      resp.sendError(WebdavStatus.SC_METHOD_NOT_ALLOWED);
                      return false;
                  }
  
                  errorList = new Hashtable<String, Integer>();
  
                  destinationSo = store.getStoredObject(transaction, destinationPath);
  
                  if (overwrite) {
  
                      // Delete destination resource, if it exists
                      if (destinationSo != null) {
                          doDelete.deleteResource(transaction, destinationPath, errorList, req, resp);
                      } else {
                          resp.setStatus(WebdavStatus.SC_CREATED);
                      }
                  } else {
                      // If the destination exists, then it's a conflict
                      if (destinationSo != null) {
                          resp.sendError(WebdavStatus.SC_PRECONDITION_FAILED);
                          return false;
                      }
                      resp.setStatus(WebdavStatus.SC_CREATED);
  
                  }
                  copy(transaction, path, destinationPath, errorList, req, resp);
  
                  if (!errorList.isEmpty()) {
                      sendReport(req, resp, errorList);
                  }
  
              } finally {
                  resourceLocks.unlockTemporaryLockedObjects(transaction, destinationPath, lockOwner);
              }
          } else {
              resp.sendError(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
              return false;
          }
          return true;
  
      }