Repository: dita-ot/dita-ot
Issue: Error in mapref stage when passing dita map as resource

I'm attaching a sample DITA project
[chemistry_crash_single_topic.zip](https://github.com/dita-ot/dita-ot/files/6242590/chemistry_crash_single_topic.zip)

on Windows I'm running this command line:
```batch
dita -i C:\\Users\\radu_coravu\\Downloads\\chemistry_crash_single_topic\\iugux\\installation_preparation\\overview_of_installation_process.dita ^
  --resource=C:\\Users\\radu_coravu\\Downloads\\chemistry_crash_single_topic\\iugux.ditamap ^
  -f html5 ^
  --temp=tmp ^
  --clean.temp=no ^
  -v
```

then I get an error reported in the "mapref" stage:

     [mapref]   I/O error reported by XML parser processing
     [mapref]   file:/C:/Users/radu_coravu/Desktop/dita-ot-3.6/bin/tmp/C:/Users/radu_coravu/Downloads/chemistry_crash_single_topic/iugux.ditamap: C:\\Users\\radu_coravu\\Desktop\\dita-ot-3.6\\bin\\tmp\\C:\\Users\\radu_coravu\\Downloads\\chemistry_crash_single_topic\\iugux.ditamap (The filename, directory name, or volume label syntax is incorrect)

As you can see the absolute path to the dita map gets concatenated to the absolute path to the temporary files folder, producing an invalid file path on Windows.
Looking in the .job.xml at the entry for the DITA Map:

```xml
        <file src="file:/C:/Users/radu_coravu/Downloads/chemistry_crash_single_topic/iugux.ditamap"
            uri="file:/C:/Users/radu_coravu/Downloads/chemistry_crash_single_topic/iugux.ditamap"
            path="C:\\Users\\radu_coravu\\Downloads\\chemistry_crash_single_topic\\iugux.ditamap"
            result="file:/C:/Users/radu_coravu/Downloads/chemistry_crash_single_topic/iugux.ditamap"
            format="ditamap" resource-only="true"/>
```
it is the only entry with an absolute `@path` attribute.

When the method "org.dita.dost.module.MaprefModule.processMap(FileInfo)" gets called, the input file gets computed by appending two absolute file paths one to another:

```java
    File inputFile = new File(job.tempDir, input.file.getPath());
```
which is invalid on Windows.

The same thing works on Mac because the file path does not contain a drive name and "new File(job.tempDir, input.file.getPath())" manages to produce a valid file path.

Changed files:
src/main/java/org/dita/dost/module/MoveMetaModule.java, src/main/java/org/dita/dost/module/ImageMetadataModule.java, src/main/java/org/dita/dost/module/reader/AbstractReaderModule.java, src/main/java/org/dita/dost/ant/types/JobSourceSet.java, src/main/java/org/dita/dost/module/MaprefModule.java, src/main/java/org/dita/dost/module/DebugAndFilterModule.java, src/main/java/org/dita/dost/reader/MergeTopicParser.java, src/main/java/org/dita/dost/util/FileUtils.java, src/main/java/org/dita/dost/module/filter/AbstractBranchFilterModule.java, src/main/java/org/dita/dost/module/ConrefPushModule.java, src/main/java/org/dita/dost/module/KeyrefModule.java, src/main/java/org/dita/dost/module/GenMapAndTopicListModule.java, src/main/java/org/dita/dost/reader/MergeMapParser.java, src/main/java/org/dita/dost/module/ChunkModule.java, src/main/java/org/dita/dost/module/XsltModule.java, src/test/java/org/dita/dost/util/TestFileUtils.java

diff --git a/src/main/java/org/dita/dost/ant/types/JobSourceSet.java b/src/main/java/org/dita/dost/ant/types/JobSourceSet.java
index bfa79b2f6..935db7257 100644
--- a/src/main/java/org/dita/dost/ant/types/JobSourceSet.java
+++ b/src/main/java/org/dita/dost/ant/types/JobSourceSet.java
@@ -7,10 +7,6 @@
  */
 package org.dita.dost.ant.types;
 
-import static org.dita.dost.util.Constants.*;
-import static org.dita.dost.util.FileUtils.supportedImageExtensions;
-import static org.dita.dost.util.URLUtils.*;
-
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.ImmutableSet;
 import org.apache.tools.ant.Project;
@@ -32,6 +28,11 @@ import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.*;
 
+import static org.dita.dost.util.Constants.ATTR_FORMAT_VALUE_DITA;
+import static org.dita.dost.util.Constants.ATTR_FORMAT_VALUE_IMAGE;
+import static org.dita.dost.util.FileUtils.supportedImageExtensions;
+import static org.dita.dost.util.URLUtils.toFile;
+
 /**
  * Resource collection that finds matching resources from job configuration.
  */
@@ -59,7 +60,7 @@ public class JobSourceSet extends AbstractFileSet implements ResourceCollection
             res = new ArrayList<>();
             for (final FileInfo f : job.getFileInfo(this::filter)) {
                 log("Scanning for " + f.file.getPath(), Project.MSG_VERBOSE);
-                final File tempFile = new File(job.tempDir, f.file.getPath());
+                final File tempFile = new File(job.tempDirURI.resolve(f.uri));
                 if (job.getStore().exists(tempFile.toURI())) {
                     log("Found temporary directory file " + tempFile, Project.MSG_VERBOSE);
                     res.add(new StoreResource(job, job.tempDirURI.relativize(f.uri)));
diff --git a/src/main/java/org/dita/dost/module/ChunkModule.java b/src/main/java/org/dita/dost/module/ChunkModule.java
index 4515662d0..dfc8a4db1 100644
--- a/src/main/java/org/dita/dost/module/ChunkModule.java
+++ b/src/main/java/org/dita/dost/module/ChunkModule.java
@@ -73,7 +73,7 @@ final public class ChunkModule extends AbstractPipelineModuleImpl {
             if (transtype.equals(INDEX_TYPE_ECLIPSEHELP) && isEclipseMap(mapFile.toURI())) {
                 for (final FileInfo f : job.getFileInfo()) {
                     if (ATTR_FORMAT_VALUE_DITAMAP.equals(f.format)) {
-                        mapReader.read(new File(job.tempDir, f.file.getPath()).getAbsoluteFile());
+                        mapReader.read(new File(job.tempDirURI.resolve(f.uri)).getAbsoluteFile());
                     }
                 }
             } else {
diff --git a/src/main/java/org/dita/dost/module/ConrefPushModule.java b/src/main/java/org/dita/dost/module/ConrefPushModule.java
index cbf8310af..a4ba2ccd4 100644
--- a/src/main/java/org/dita/dost/module/ConrefPushModule.java
+++ b/src/main/java/org/dita/dost/module/ConrefPushModule.java
@@ -8,12 +8,6 @@
  */
 package org.dita.dost.module;
 
-import java.io.File;
-import java.util.Collection;
-import java.util.Hashtable;
-import java.util.Map;
-import java.util.stream.Collectors;
-
 import org.dita.dost.exception.DITAOTException;
 import org.dita.dost.pipeline.AbstractPipelineInput;
 import org.dita.dost.pipeline.AbstractPipelineOutput;
@@ -23,6 +17,12 @@ import org.dita.dost.util.Job.FileInfo;
 import org.dita.dost.writer.ConrefPushParser;
 import org.w3c.dom.DocumentFragment;
 
+import java.io.File;
+import java.util.Collection;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.stream.Collectors;
+
 /**
  * Conref push module.
  */
@@ -38,7 +38,7 @@ final class ConrefPushModule extends AbstractPipelineModuleImpl {
             reader.setLogger(logger);
             reader.setJob(job);
             for (final FileInfo f: fis) {
-                final File file = new File(job.tempDir, f.file.getPath());
+                final File file = new File(job.tempDirURI.resolve(f.uri));
                 logger.info("Reading " + file.toURI());
                 //FIXME: this reader calculate parent directory
                 reader.read(file.getAbsoluteFile());
diff --git a/src/main/java/org/dita/dost/module/DebugAndFilterModule.java b/src/main/java/org/dita/dost/module/DebugAndFilterModule.java
index f063f3c1e..0819699b9 100644
--- a/src/main/java/org/dita/dost/module/DebugAndFilterModule.java
+++ b/src/main/java/org/dita/dost/module/DebugAndFilterModule.java
@@ -119,7 +119,7 @@ public final class DebugAndFilterModule extends SourceReaderModule {
             logger.warn("Ignoring a copy-to file " + f.result);
             return;
         }
-        outputFile = new File(job.tempDir, f.file.getPath());
+        outputFile = new File(job.tempDirURI.resolve(f.uri));
         logger.info("Processing " + f.src + " to " + outputFile.toURI());
 
         final Set<URI> schemaSet = dic.get(f.uri);
diff --git a/src/main/java/org/dita/dost/module/GenMapAndTopicListModule.java b/src/main/java/org/dita/dost/module/GenMapAndTopicListModule.java
index f9fd0f90b..2dfa77c28 100644
--- a/src/main/java/org/dita/dost/module/GenMapAndTopicListModule.java
+++ b/src/main/java/org/dita/dost/module/GenMapAndTopicListModule.java
@@ -1035,7 +1035,7 @@ public final class GenMapAndTopicListModule extends SourceReaderModule {
         // write list attribute to file
         final String fileKey = REL_FLAGIMAGE_LIST.substring(0, REL_FLAGIMAGE_LIST.lastIndexOf("list")) + "file";
         prop.setProperty(fileKey, REL_FLAGIMAGE_LIST.substring(0, REL_FLAGIMAGE_LIST.lastIndexOf("list")) + ".list");
-        final File list = new File(job.tempDir, prop.getProperty(fileKey));
+        final File list = job.tempDir.toPath().resolve(prop.getProperty(fileKey)).toFile();
         try (Writer bufferedWriter = new BufferedWriter(new OutputStreamWriter(job.getStore().getOutputStream(list.toURI())))) {
             final Iterator<URI> it = newSet.iterator();
             while (it.hasNext()) {
diff --git a/src/main/java/org/dita/dost/module/ImageMetadataModule.java b/src/main/java/org/dita/dost/module/ImageMetadataModule.java
index f317b6414..05090974f 100644
--- a/src/main/java/org/dita/dost/module/ImageMetadataModule.java
+++ b/src/main/java/org/dita/dost/module/ImageMetadataModule.java
@@ -7,7 +7,13 @@
  */
 package org.dita.dost.module;
 
-import static org.dita.dost.util.Constants.*;
+import org.dita.dost.exception.DITAOTException;
+import org.dita.dost.pipeline.AbstractPipelineInput;
+import org.dita.dost.pipeline.AbstractPipelineOutput;
+import org.dita.dost.util.Job.FileInfo;
+import org.dita.dost.util.Pool;
+import org.dita.dost.writer.ImageMetadataFilter;
+import org.xml.sax.Attributes;
 
 import java.io.File;
 import java.io.IOException;
@@ -16,15 +22,8 @@ import java.util.Collection;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.Predicate;
-import java.util.stream.Stream;
 
-import org.dita.dost.exception.DITAOTException;
-import org.dita.dost.pipeline.AbstractPipelineInput;
-import org.dita.dost.pipeline.AbstractPipelineOutput;
-import org.dita.dost.util.Job.FileInfo;
-import org.dita.dost.util.Pool;
-import org.dita.dost.writer.ImageMetadataFilter;
-import org.xml.sax.Attributes;
+import static org.dita.dost.util.Constants.*;
 
 /**
  * Image metadata module.
@@ -68,7 +67,7 @@ final class ImageMetadataModule extends AbstractPipelineModuleImpl {
                 });
                 job.getFileInfo(filter).stream()
                         .parallel()
-                        .map(f -> new File(job.tempDir, f.file.getPath()).getAbsoluteFile())
+                        .map(f -> new File(job.tempDirURI.resolve(f.uri)).getAbsoluteFile())
                         .forEach(filename -> {
                             final ImageMetadataFilter writer = pool.borrowObject();
                             try {
@@ -82,7 +81,7 @@ final class ImageMetadataModule extends AbstractPipelineModuleImpl {
                 writer.setLogger(logger);
                 writer.setJob(job);
                 for (final FileInfo f : job.getFileInfo(filter)) {
-                    writer.write(new File(job.tempDir, f.file.getPath()).getAbsoluteFile());
+                    writer.write(new File(job.tempDirURI.resolve(f.uri)).getAbsoluteFile());
                 }
             }
 
diff --git a/src/main/java/org/dita/dost/module/KeyrefModule.java b/src/main/java/org/dita/dost/module/KeyrefModule.java
index b3a8270fc..edb939e25 100644
--- a/src/main/java/org/dita/dost/module/KeyrefModule.java
+++ b/src/main/java/org/dita/dost/module/KeyrefModule.java
@@ -32,7 +32,6 @@ import org.dita.dost.writer.KeyrefPaser;
 import org.dita.dost.writer.TopicFragmentFilter;
 import org.xml.sax.XMLFilter;
 
-import java.io.File;
 import java.io.IOException;
 import java.net.URI;
 import java.util.*;
@@ -499,12 +498,12 @@ final class KeyrefModule extends AbstractPipelineModuleImpl {
             if (r.out != null) {
                 logger.info("Processing " + job.tempDirURI.resolve(r.in.uri) +
                         " to " + job.tempDirURI.resolve(r.out.uri));
-                job.getStore().transform(new File(job.tempDir, r.in.file.getPath()).toURI(),
-                        new File(job.tempDir, r.out.file.getPath()).toURI(),
+                job.getStore().transform(job.tempDirURI.resolve(r.in.uri),
+                        job.tempDirURI.resolve(r.out.uri),
                         filters);
             } else {
                 logger.info("Processing " + job.tempDirURI.resolve(r.in.uri));
-                job.getStore().transform(new File(job.tempDir, r.in.file.getPath()).toURI(),
+                job.getStore().transform(job.tempDirURI.resolve(r.in.uri),
                         filters);
             }
             // validate resource-only list
diff --git a/src/main/java/org/dita/dost/module/MaprefModule.java b/src/main/java/org/dita/dost/module/MaprefModule.java
index fd624f997..c6359c124 100644
--- a/src/main/java/org/dita/dost/module/MaprefModule.java
+++ b/src/main/java/org/dita/dost/module/MaprefModule.java
@@ -87,7 +87,7 @@ final class MaprefModule extends AbstractPipelineModuleImpl {
     }
 
     private void processMap(final FileInfo input) throws DITAOTException {
-        final File inputFile = new File(job.tempDir, input.file.getPath());
+        final File inputFile = new File(job.tempDirURI.resolve(input.uri));
         final File outputFile = new File(inputFile.getAbsolutePath() + FILE_EXTENSION_TEMP);
 
         logger.info("Processing " + inputFile.toURI());
@@ -160,8 +160,8 @@ final class MaprefModule extends AbstractPipelineModuleImpl {
     }
 
     private void replace(final FileInfo input) throws DITAOTException {
-        final File inputFile = new File(job.tempDir, input.file.getPath() + FILE_EXTENSION_TEMP);
-        final File outputFile = new File(job.tempDir, input.file.getPath());
+        final File inputFile = new File(job.tempDirURI.resolve(input.uri + FILE_EXTENSION_TEMP));
+        final File outputFile = new File(job.tempDirURI.resolve(input.uri));
         try {
             job.getStore().move(inputFile.toURI(), outputFile.toURI());
         } catch (final IOException e) {
diff --git a/src/main/java/org/dita/dost/module/MoveMetaModule.java b/src/main/java/org/dita/dost/module/MoveMetaModule.java
index c24634ce0..3275f2866 100644
--- a/src/main/java/org/dita/dost/module/MoveMetaModule.java
+++ b/src/main/java/org/dita/dost/module/MoveMetaModule.java
@@ -80,7 +80,7 @@ final class MoveMetaModule extends AbstractPipelineModuleImpl {
         }
 
         for (final FileInfo f : fis) {
-            final File inputFile = new File(job.tempDir, f.file.getPath());
+            final File inputFile = new File(job.tempDirURI.resolve(f.uri));
             final File tmp = new File(inputFile.getAbsolutePath() + ".tmp" + Long.toString(System.currentTimeMillis()));
             logger.info("Processing " + inputFile.toURI());
             logger.debug("Processing " + inputFile.toURI() + " to " + tmp.toURI());
@@ -133,7 +133,7 @@ final class MoveMetaModule extends AbstractPipelineModuleImpl {
                 final URI key = stripFragment(entry.getKey());
                 final FileInfo fi = job.getFileInfo(key);
                 if (fi == null) {
-                    logger.error("File " + new File(job.tempDir, key.getPath()) + " was not found.");
+                    logger.error("File " + job.tempDirURI.resolve(key) + " was not found.");
                     continue;
                 }
                 final URI targetFileName = job.tempDirURI.resolve(fi.uri);
@@ -159,7 +159,7 @@ final class MoveMetaModule extends AbstractPipelineModuleImpl {
                 final URI key = stripFragment(entry.getKey());
                 final FileInfo fi = job.getFileInfo(key);
                 if (fi == null) {
-                    logger.error("File " + new File(job.tempDir, key.getPath()) + " was not found.");
+                    logger.error("File " + job.tempDirURI.resolve(key) + " was not found.");
                     continue;
                 }
                 final URI targetFileName = job.tempDirURI.resolve(fi.uri);
@@ -186,7 +186,7 @@ final class MoveMetaModule extends AbstractPipelineModuleImpl {
         metaReader.setLogger(logger);
         metaReader.setJob(job);
         for (final FileInfo f : fis) {
-            final File mapFile = new File(job.tempDir, f.file.getPath());
+            final File mapFile = job.tempDir.toPath().resolve(f.file.toPath()).toFile();
             //FIXME: this reader gets the parent path of input file
             try {
                 metaReader.read(mapFile);
diff --git a/src/main/java/org/dita/dost/module/XsltModule.java b/src/main/java/org/dita/dost/module/XsltModule.java
index e034a4f11..22c8214ba 100644
--- a/src/main/java/org/dita/dost/module/XsltModule.java
+++ b/src/main/java/org/dita/dost/module/XsltModule.java
@@ -114,7 +114,7 @@ public final class XsltModule extends AbstractPipelineModuleImpl {
                 final List<Entry<File, File>> tmps = includes.stream().parallel()
                         .map(include -> {
                             try {
-                                final File in = new File(baseDir, include.getPath());
+                                final File in = baseDir.toPath().resolve(include.toPath()).toFile();
                                 final File out = getOutput(include.getPath());
                                 if (out == null) {
                                     return null;
@@ -159,7 +159,7 @@ public final class XsltModule extends AbstractPipelineModuleImpl {
     }
 
     private File getOutput(final String path) {
-        File out = new File(destDir, path);
+        File out = destDir.toPath().resolve(path).toFile();
         if (mapper != null) {
             final String[] outs = mapper.mapFileName(path);
             if (outs == null) {
@@ -168,7 +168,7 @@ public final class XsltModule extends AbstractPipelineModuleImpl {
             if (outs.length > 1) {
                 throw new RuntimeException("XSLT module only support one to one output mapping");
             }
-            out = new File(destDir, outs[0]);
+            out = destDir.toPath().resolve(outs[0]).toFile();
         } else if (extension != null) {
             out = new File(replaceExtension(out.getAbsolutePath(), extension));
         }
diff --git a/src/main/java/org/dita/dost/module/filter/AbstractBranchFilterModule.java b/src/main/java/org/dita/dost/module/filter/AbstractBranchFilterModule.java
index dd5d44c66..f0a7aa88c 100644
--- a/src/main/java/org/dita/dost/module/filter/AbstractBranchFilterModule.java
+++ b/src/main/java/org/dita/dost/module/filter/AbstractBranchFilterModule.java
@@ -154,7 +154,7 @@ public abstract class AbstractBranchFilterModule extends AbstractPipelineModuleI
         // write list attribute to file
         final String fileKey = REL_FLAGIMAGE_LIST.substring(0, REL_FLAGIMAGE_LIST.lastIndexOf("list")) + "file";
         prop.setProperty(fileKey, REL_FLAGIMAGE_LIST.substring(0, REL_FLAGIMAGE_LIST.lastIndexOf("list")) + ".list");
-        final File list = new File(job.tempDir, prop.getProperty(fileKey));
+        final File list = job.tempDir.toPath().resolve(prop.getProperty(fileKey)).toFile();
         try (Writer bufferedWriter = new BufferedWriter(new OutputStreamWriter(job.getStore().getOutputStream(list.toURI())))) {
             for (URI aNewSet : newSet) {
                 bufferedWriter.write(aNewSet.getPath());
diff --git a/src/main/java/org/dita/dost/module/reader/AbstractReaderModule.java b/src/main/java/org/dita/dost/module/reader/AbstractReaderModule.java
index b55d8ca83..2e7eec0d7 100644
--- a/src/main/java/org/dita/dost/module/reader/AbstractReaderModule.java
+++ b/src/main/java/org/dita/dost/module/reader/AbstractReaderModule.java
@@ -33,7 +33,6 @@ import java.nio.file.FileAlreadyExistsException;
 import java.nio.file.Files;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.ConcurrentSkipListMap;
 import java.util.function.Consumer;
 import java.util.function.Predicate;
@@ -915,7 +914,7 @@ public abstract class AbstractReaderModule extends AbstractPipelineModuleImpl {
         // write list attribute to file
         final String fileKey = REL_FLAGIMAGE_LIST.substring(0, REL_FLAGIMAGE_LIST.lastIndexOf("list")) + "file";
         prop.setProperty(fileKey, REL_FLAGIMAGE_LIST.substring(0, REL_FLAGIMAGE_LIST.lastIndexOf("list")) + ".list");
-        final File list = new File(job.tempDir, prop.getProperty(fileKey));
+        final File list = job.tempDir.toPath().resolve(prop.getProperty(fileKey)).toFile();
         try (Writer bufferedWriter = new BufferedWriter(new OutputStreamWriter(job.getStore().getOutputStream(list.toURI())))) {
             for (URI aNewSet : newSet) {
                 bufferedWriter.write(aNewSet.getPath());
diff --git a/src/main/java/org/dita/dost/reader/MergeMapParser.java b/src/main/java/org/dita/dost/reader/MergeMapParser.java
index aae040e70..e484d81ed 100644
--- a/src/main/java/org/dita/dost/reader/MergeMapParser.java
+++ b/src/main/java/org/dita/dost/reader/MergeMapParser.java
@@ -8,36 +8,29 @@
  */
 package org.dita.dost.reader;
 
-import static javax.xml.transform.OutputKeys.*;
-import static org.dita.dost.chunk.ChunkModule.isLocalScope;
-import static org.dita.dost.util.Constants.*;
-import static org.dita.dost.util.URLUtils.*;
+import org.dita.dost.log.DITAOTLogger;
+import org.dita.dost.log.MessageUtils;
+import org.dita.dost.util.*;
+import org.dita.dost.util.Job.FileInfo;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+import org.xml.sax.helpers.XMLFilterImpl;
 
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.stream.StreamResult;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.OutputStream;
 import java.net.URI;
 import java.util.Stack;
 
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.sax.SAXTransformerFactory;
-import javax.xml.transform.sax.TransformerHandler;
-import javax.xml.transform.stream.StreamResult;
-
-import org.xml.sax.helpers.XMLFilterImpl;
-import org.xml.sax.helpers.AttributesImpl;
-
-import org.dita.dost.log.DITAOTLogger;
-import org.dita.dost.log.MessageUtils;
-import org.dita.dost.util.FileUtils;
-import org.dita.dost.util.Job;
-import org.dita.dost.util.Job.FileInfo;
-import org.dita.dost.util.MergeUtils;
-import org.dita.dost.util.URLUtils;
-import org.dita.dost.util.XMLUtils;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
+import static javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION;
+import static org.dita.dost.chunk.ChunkModule.isLocalScope;
+import static org.dita.dost.util.Constants.*;
+import static org.dita.dost.util.URLUtils.*;
 
 /**
  * MergeMapParser reads the ditamap file after preprocessing and merges
@@ -250,14 +243,14 @@ public final class MergeMapParser extends XMLFilterImpl {
                     String element = f.file.getPath();
                     if (!dirPath.equals(tempdir)) {
                         element = FileUtils.getRelativeUnixPath(new File(dirPath,"a.ditamap").getAbsolutePath(),
-                                                                   new File(tempdir, element).getAbsolutePath());
+                                                                   tempdir.toPath().resolve(element).toAbsolutePath().toString());
                     }
                     final URI abs = job.tempDirURI.resolve(f.uri);
                     if (!util.isVisited(abs)) {
                         util.visit(abs);
                         if (!f.isResourceOnly) {
                             //ensure the file exists
-                            final File file = new File(dirPath, element);
+                            final File file = dirPath.toPath().resolve(element).toFile();
                             if (job.getStore().exists(file.toURI())) {
                                 topicParser.parse(element, dirPath);
                             } else {
diff --git a/src/main/java/org/dita/dost/reader/MergeTopicParser.java b/src/main/java/org/dita/dost/reader/MergeTopicParser.java
index 8ce4a4191..010715af4 100644
--- a/src/main/java/org/dita/dost/reader/MergeTopicParser.java
+++ b/src/main/java/org/dita/dost/reader/MergeTopicParser.java
@@ -8,17 +8,6 @@
  */
 package org.dita.dost.reader;
 
-import static javax.xml.XMLConstants.*;
-import static org.dita.dost.chunk.ChunkModule.isLocalScope;
-import static org.dita.dost.reader.MergeMapParser.*;
-import static org.dita.dost.util.Constants.*;
-import static org.dita.dost.util.FileUtils.*;
-import static org.dita.dost.util.URLUtils.*;
-import static org.dita.dost.util.URLUtils.setFragment;
-
-import java.io.File;
-import java.net.URI;
-
 import org.dita.dost.log.DITAOTLogger;
 import org.dita.dost.util.Job;
 import org.dita.dost.util.MergeUtils;
@@ -29,6 +18,17 @@ import org.xml.sax.SAXException;
 import org.xml.sax.helpers.AttributesImpl;
 import org.xml.sax.helpers.XMLFilterImpl;
 
+import java.io.File;
+import java.net.URI;
+
+import static javax.xml.XMLConstants.XML_NS_URI;
+import static org.dita.dost.chunk.ChunkModule.isLocalScope;
+import static org.dita.dost.reader.MergeMapParser.ATTRIBUTE_NAME_OHREF;
+import static org.dita.dost.reader.MergeMapParser.ATTRIBUTE_NAME_OID;
+import static org.dita.dost.util.Constants.*;
+import static org.dita.dost.util.FileUtils.stripFragment;
+import static org.dita.dost.util.URLUtils.*;
+
 /**
  * MergeTopicParser reads topic file and transform the references to other dita
  * files into internal references. The parse result of MergeTopicParser will be
@@ -174,7 +174,7 @@ public final class MergeTopicParser extends XMLFilterImpl {
         filePath = stripFragment(filename);
         dirPath = dir;
         try {
-            final URI f = new File(dir, filePath).getAbsoluteFile().toURI();
+            final URI f = dir.toPath().resolve(filePath).toAbsolutePath().toFile().toURI();
             logger.info("Processing " + f);
             job.getStore().transform(f, this);
         } catch (final RuntimeException e) {
@@ -251,7 +251,7 @@ public final class MergeTopicParser extends XMLFilterImpl {
      * @return rewritten href value
      */
     private URI handleLocalHref(final URI attValue) {
-        final URI current = new File(dirPath, filePath).toURI().normalize();
+        final URI current = dirPath.toPath().resolve(filePath).toUri().normalize();
         final URI reference = current.resolve(attValue);
         final URI merge = output.toURI();
         return getRelativePath(merge, reference);
diff --git a/src/main/java/org/dita/dost/util/FileUtils.java b/src/main/java/org/dita/dost/util/FileUtils.java
index e0544f85d..1bd6ee369 100644
--- a/src/main/java/org/dita/dost/util/FileUtils.java
+++ b/src/main/java/org/dita/dost/util/FileUtils.java
@@ -8,13 +8,13 @@
  */
 package org.dita.dost.util;
 
-import static org.apache.commons.io.FilenameUtils.*;
-import static org.dita.dost.util.Constants.*;
-
 import java.io.File;
 import java.net.URI;
 import java.util.*;
 
+import static org.apache.commons.io.FilenameUtils.normalize;
+import static org.dita.dost.util.Constants.*;
+
 /**
  * Static file utilities.
  *
diff --git a/src/test/java/org/dita/dost/util/TestFileUtils.java b/src/test/java/org/dita/dost/util/TestFileUtils.java
index 3110579ef..85a06d56a 100644
--- a/src/test/java/org/dita/dost/util/TestFileUtils.java
+++ b/src/test/java/org/dita/dost/util/TestFileUtils.java
@@ -7,16 +7,15 @@
  */
 package org.dita.dost.util;
 
-import static org.junit.Assert.*;
-import static org.junit.Assert.assertEquals;
-
-import java.io.*;
-
+import org.dita.dost.TestUtils;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
-import org.dita.dost.TestUtils;
+import java.io.File;
+import java.io.IOException;
+
+import static org.junit.Assert.*;
 
 public class TestFileUtils {