@Override
  public void deleteFile(SrvSession sess, TreeConnection tree, String name) throws IOException {
    if (logger.isDebugEnabled()) {
      logger.debug("deleteFile name:" + name);
    }
    try {
      ContentContext tctx = (ContentContext) tree.getContext();
      NodeRef rootNode = tctx.getRootNode();

      DriverState driverState = getDriverState(sess);

      String[] paths = FileName.splitPath(name);
      String folder = paths[0];
      String file = paths[1];

      EvaluatorContext ctx = getEvaluatorContext(driverState, folder);

      Operation o = new DeleteFileOperation(file, rootNode, name);
      Command c = ruleEvaluator.evaluate(ctx, o);
      commandExecutor.execute(sess, tree, c);

      releaseEvaluatorContextIfEmpty(driverState, ctx, folder);
    } catch (org.alfresco.repo.security.permissions.AccessDeniedException ade) {
      throw new AccessDeniedException("Unable to delete file " + name, ade);
    }
  } // End of deleteFile
 /**
  * Get the evaluator context from the state and the folder.
  *
  * @param driverState
  * @param folder
  * @return
  */
 private EvaluatorContext getEvaluatorContext(DriverState driverState, String folder) {
   synchronized (driverState.contextMap) {
     EvaluatorContext ctx = driverState.contextMap.get(folder);
     if (ctx == null) {
       ctx = ruleEvaluator.createContext(driverState.sessionState);
       driverState.contextMap.put(folder, ctx);
       if (logger.isDebugEnabled()) {
         logger.debug("new driver context: " + folder);
       }
     }
     return ctx;
   }
 }
  @Override
  public void closeFile(SrvSession sess, TreeConnection tree, NetworkFile param)
      throws IOException {
    if (logger.isDebugEnabled()) {
      logger.debug("closeFile:" + param.getFullName());
    }

    ContentContext tctx = (ContentContext) tree.getContext();
    NodeRef rootNode = tctx.getRootNode();

    DriverState driverState = getDriverState(sess);

    String[] paths = FileName.splitPath(param.getFullName());
    String folder = paths[0];
    String file = paths[1];

    try {
      EvaluatorContext ctx = getEvaluatorContext(driverState, folder);

      Operation o =
          new CloseFileOperation(
              file,
              param,
              rootNode,
              param.getFullName(),
              param.hasDeleteOnClose(),
              param.isForce());
      Command c = ruleEvaluator.evaluate(ctx, o);

      commandExecutor.execute(sess, tree, c);

      releaseEvaluatorContextIfEmpty(driverState, ctx, folder);
    } catch (org.alfresco.repo.security.permissions.AccessDeniedException ade) {
      throw new AccessDeniedException("Unable to close file " + param.getFullName(), ade);
    }
  }
  @Override
  public void renameFile(SrvSession sess, TreeConnection tree, String oldPath, String newPath)
      throws IOException {
    ContentContext tctx = (ContentContext) tree.getContext();
    NodeRef rootNode = tctx.getRootNode();

    if (logger.isDebugEnabled()) {
      logger.debug("renameFile oldPath:" + oldPath + ", newPath:" + newPath);
    }

    DriverState driverState = getDriverState(sess);

    // Is this a rename within the same folder or a move between folders?

    String[] paths = FileName.splitPath(oldPath);
    String oldFolder = paths[0];
    String oldFile = paths[1];

    paths = FileName.splitPath(newPath);
    String newFolder = paths[0];
    String newFile = paths[1];

    try {
      if (oldFolder.equalsIgnoreCase(newFolder)) {
        logger.debug("renameFileCommand - is a rename within the same folder");

        EvaluatorContext ctx = getEvaluatorContext(driverState, oldFolder);

        Operation o = new RenameFileOperation(oldFile, newFile, oldPath, newPath, rootNode);
        Command c = ruleEvaluator.evaluate(ctx, o);
        commandExecutor.execute(sess, tree, c);

        ruleEvaluator.notifyRename(ctx, o, c);

        releaseEvaluatorContextIfEmpty(driverState, ctx, oldFolder);

      } else {
        logger.debug("moveFileCommand - move between folders");

        Operation o = new MoveFileOperation(oldFile, newFile, oldPath, newPath, rootNode);

        /*
         * Note: At the moment we only have move scenarios for the destination folder - so
         * we only need to evaluate against a single (destination) context/folder.
         * This will require re-design as and when we need to have scenarios for the source/folder
         */

        // EvaluatorContext ctx1 = getEvaluatorContext(driverState, oldFolder);
        EvaluatorContext ctx2 = getEvaluatorContext(driverState, newFolder);

        Command c = ruleEvaluator.evaluate(ctx2, o);

        commandExecutor.execute(sess, tree, c);

        releaseEvaluatorContextIfEmpty(driverState, ctx2, newFolder);

        //  diskInterface.renameFile(sess, tree, oldPath, newPath);

      }
    } catch (org.alfresco.repo.security.permissions.AccessDeniedException ade) {
      throw new AccessDeniedException("Unable to rename file file " + oldPath, ade);
    }
  }
  @Override
  public NetworkFile openFile(SrvSession sess, TreeConnection tree, FileOpenParams param)
      throws IOException {
    String path = param.getPath();

    boolean truncate = param.isOverwrite();

    if (logger.isDebugEnabled()) {
      int sharedAccess = param.getSharedAccess();
      String strSharedAccess = SharingMode.getSharingModeAsString(sharedAccess);

      logger.debug(
          "openFile:"
              + path
              + ", isDirectory: "
              + param.isDirectory()
              + ", isStream: "
              + param.isStream()
              + ", readOnlyAccess: "
              + param.isReadOnlyAccess()
              + ", readWriteAccess: "
              + param.isReadWriteAccess()
              + ", writeOnlyAccess:"
              + param.isWriteOnlyAccess()
              + ", attributesOnlyAccess:"
              + param.isAttributesOnlyAccess()
              + ", sequentialAccessOnly:"
              + param.isSequentialAccessOnly()
              + ", writeThrough:"
              + param.isWriteThrough()
              + ", truncate:"
              + truncate
              + ", requestBatchOpLock:"
              + param.requestBatchOpLock()
              + ", requestExclusiveOpLock:"
              + param.requestExclusiveOpLock()
              + ", isDeleteOnClose:"
              + param.isDeleteOnClose()
              + ", allocationSize:"
              + param.getAllocationSize()
              + ", sharedAccess: "
              + strSharedAccess
              + ", openAction: "
              + param.getOpenAction()
              + param);
    }

    ContentContext tctx = (ContentContext) tree.getContext();
    NodeRef rootNode = tctx.getRootNode();

    DriverState driverState = getDriverState(sess);

    String[] paths = FileName.splitPath(path);
    String folder = paths[0];
    String file = paths[1];

    EvaluatorContext ctx = getEvaluatorContext(driverState, folder);

    OpenFileMode openMode = OpenFileMode.READ_ONLY;

    if (param.isAttributesOnlyAccess()) {
      openMode = OpenFileMode.ATTRIBUTES_ONLY;
    } else if (param.isReadWriteAccess()) {
      openMode = OpenFileMode.READ_WRITE;
    } else if (param.isWriteOnlyAccess()) {
      openMode = OpenFileMode.WRITE_ONLY;
    } else if (param.isReadOnlyAccess()) {
      openMode = OpenFileMode.READ_ONLY;
    } else if (param.isDeleteOnClose()) {
      if (logger.isDebugEnabled()) {
        logger.debug("open file has delete on close");
      }
      openMode = OpenFileMode.DELETE;
    }

    try {
      Operation o = new OpenFileOperation(file, openMode, truncate, rootNode, path);
      Command c = ruleEvaluator.evaluate(ctx, o);
      Object ret = commandExecutor.execute(sess, tree, c);

      if (ret != null && ret instanceof NetworkFile) {
        NetworkFile x = (NetworkFile) ret;

        if (logger.isDebugEnabled()) {
          logger.debug("returning open file: for path:" + path + ", ret:" + ret);
        }
        return x;
      } else {
        // Error - contact broken
        logger.error(
            "contract broken - NetworkFile not returned. " + ret == null
                ? "Return value is null"
                : ret);
        return null;
      }
    } catch (org.alfresco.repo.security.permissions.AccessDeniedException ade) {
      throw new AccessDeniedException("Unable to open file " + param.getPath(), ade);
    }

    // return diskInterface.openFile(sess, tree, params);
  } // End of OpenFile
  @Override
  public NetworkFile createFile(SrvSession sess, TreeConnection tree, FileOpenParams params)
      throws IOException {
    try {
      int attr = params.getAttributes();
      if (logger.isDebugEnabled()) {
        int sharedAccess = params.getSharedAccess();
        String strSharedAccess = SharingMode.getSharingModeAsString(sharedAccess);

        logger.debug(
            "createFile:"
                + params.getPath()
                + ", isDirectory: "
                + params.isDirectory()
                + ", isStream: "
                + params.isStream()
                + ", readOnlyAccess: "
                + params.isReadOnlyAccess()
                + ", readWriteAccess: "
                + params.isReadWriteAccess()
                + ", writeOnlyAccess:"
                + params.isWriteOnlyAccess()
                + ", attributesOnlyAccess:"
                + params.isAttributesOnlyAccess()
                + ", sequentialAccessOnly:"
                + params.isSequentialAccessOnly()
                + ", requestBatchOpLock:"
                + params.requestBatchOpLock()
                + ", requestExclusiveOpLock:"
                + params.requestExclusiveOpLock()
                + ", isDeleteOnClose:"
                + params.isDeleteOnClose()
                + ", sharedAccess: "
                + strSharedAccess
                + ", allocationSize: "
                + params.getAllocationSize()
                + ", isHidden:"
                + FileAttribute.isHidden(attr)
                + ", isSystem:"
                + FileAttribute.isSystem(attr));
      }

      long creationDateTime = params.getCreationDateTime();
      if (creationDateTime != 0) {
        logger.debug("creationDateTime is set:" + new Date(creationDateTime));
      }

      ContentContext tctx = (ContentContext) tree.getContext();
      NodeRef rootNode = tctx.getRootNode();

      String[] paths = FileName.splitPath(params.getPath());
      String folder = paths[0];
      String file = paths[1];

      DriverState driverState = getDriverState(sess);
      EvaluatorContext ctx = getEvaluatorContext(driverState, folder);

      Operation o =
          new CreateFileOperation(
              file,
              rootNode,
              params.getPath(),
              params.getAllocationSize(),
              FileAttribute.isHidden(attr));
      Command c = ruleEvaluator.evaluate(ctx, o);

      Object ret = commandExecutor.execute(sess, tree, c);

      if (ret != null && ret instanceof NetworkFile) {
        return (NetworkFile) ret;
      } else {
        // Error - contact broken
        logger.error(
            "contract broken - NetworkFile not returned. " + ret == null
                ? "Return value is null"
                : ret);
        return null;
      }
    } catch (org.alfresco.repo.security.permissions.AccessDeniedException ade) {
      throw new AccessDeniedException("Unable to create file " + params.getPath(), ade);
    }
  }