public String createFileName(Exchange exchange) {
    String answer;

    // overrule takes precedence
    Object value;

    Object overrule = exchange.getIn().getHeader(Exchange.OVERRULE_FILE_NAME);
    if (overrule != null) {
      if (overrule instanceof Expression) {
        value = overrule;
      } else {
        value =
            exchange.getContext().getTypeConverter().convertTo(String.class, exchange, overrule);
      }
    } else {
      value = exchange.getIn().getHeader(Exchange.FILE_NAME);
    }

    // if we have an overrule then override the existing header to use the overrule computed name
    // from this point forward
    if (overrule != null) {
      exchange.getIn().setHeader(Exchange.FILE_NAME, value);
    }

    if (value != null
        && value instanceof String
        && StringHelper.hasStartToken((String) value, "simple")) {
      log.warn(
          "Simple expression: {} detected in header: {} of type String. This feature has been removed (see CAMEL-6748).",
          value,
          Exchange.FILE_NAME);
    }

    // expression support
    Expression expression = endpoint.getFileName();
    if (value != null && value instanceof Expression) {
      expression = (Expression) value;
    }

    // evaluate the name as a String from the value
    String name;
    if (expression != null) {
      log.trace("Filename evaluated as expression: {}", expression);
      name = expression.evaluate(exchange, String.class);
    } else {
      name = exchange.getContext().getTypeConverter().convertTo(String.class, exchange, value);
    }

    // flatten name
    if (name != null && endpoint.isFlatten()) {
      // check for both windows and unix separators
      int pos = Math.max(name.lastIndexOf("/"), name.lastIndexOf("\\"));
      if (pos != -1) {
        name = name.substring(pos + 1);
      }
    }

    // compute path by adding endpoint starting directory
    String endpointPath = endpoint.getConfiguration().getDirectory();
    String baseDir = "";
    if (endpointPath.length() > 0) {
      // Its a directory so we should use it as a base path for the filename
      // If the path isn't empty, we need to add a trailing / if it isn't already there
      baseDir = endpointPath;
      boolean trailingSlash = endpointPath.endsWith("/") || endpointPath.endsWith("\\");
      if (!trailingSlash) {
        baseDir += getFileSeparator();
      }
    }
    if (name != null) {
      answer = baseDir + name;
    } else {
      // use a generated filename if no name provided
      answer = baseDir + endpoint.getGeneratedFileName(exchange.getIn());
    }

    if (endpoint.getConfiguration().needToNormalize()) {
      // must normalize path to cater for Windows and other OS
      answer = normalizePath(answer);
    }

    return answer;
  }