package de.duehl.basics.io;

/*
 * Copyright 2025 Christian Dühl. All rights reserved.
 *
 * This program is free software. You can redistribute it and/or
 * modify it under the same terms as perl:
 *
 * general:  http://dev.perl.org/licenses/
 * GPL:      http://dev.perl.org/licenses/gpl1.html
 * artistic: http://dev.perl.org/licenses/artistic.html
 */

import static org.junit.Assert.*;

import java.io.File;
import java.util.List;

import org.junit.Test;

import de.duehl.basics.collections.CollectionsHelper;
import de.duehl.basics.io.data.FileWithModificationTime;
import de.duehl.basics.io.exceptions.IORuntimeException;
import de.duehl.basics.test.TestHelper;

public class FileHelperTest {

    private final String path;
    private final String multipeSubsDir;
    private final String theOneFileDir;

    public FileHelperTest() {
        TestHelper testHelper = TestHelper.createForBasics(getClass(), 6);
        path =  testHelper.getTestDataPath() + File.separator;

        multipeSubsDir = FileHelper.concatPathes(path, "mehrere_unterverzeichnisse");
        theOneFileDir = FileHelper.concatPathes(path, "the_one_file");
    }


    /* -------------------------- TESTS -------------------------- */


    @Test
    public void deleteTree() {
        String directory = createDirectoryStructureToDelete();

        FileHelper.deleteTree(directory);
        assertFalse(FileHelper.isDirectory(directory));
    }

    @Test
    public void deleteTreeIgnoreErrors() {
        String directory = createDirectoryStructureToDelete();

        FileHelper.deleteTreeIgnoreErrors(directory);
        assertFalse(FileHelper.isDirectory(directory));
    }

    private String createDirectoryStructureToDelete() {
        String directory = path + "dir_for_delete_tree";
        assertFalse(FileHelper.isDirectory(directory));
        FileHelper.createDirectory(directory);
        assertTrue(FileHelper.isDirectory(directory));
        String filename1 = FileHelper.concatPathes(directory, "Datei1.txt");
        String filename2 = FileHelper.concatPathes(directory, "Datei2.txt");
        String subdir = FileHelper.concatPathes(directory, "Unterverzeichnis");
        assertFalse(FileHelper.isDirectory(subdir));
        FileHelper.createDirectory(subdir);
        assertTrue(FileHelper.isDirectory(subdir));
        String filename3 = FileHelper.concatPathes(subdir, "Datei3.txt");
        assertFalse(FileHelper.isFile(filename1));
        assertFalse(FileHelper.isFile(filename2));
        assertFalse(FileHelper.isFile(filename3));
        FileHelper.writeTextToFile("Beispieldatei", filename1);
        FileHelper.writeTextToFile("Beispieldatei", filename2);
        FileHelper.writeTextToFile("Beispieldatei", filename3);
        assertTrue(FileHelper.isFile(filename1));
        assertTrue(FileHelper.isFile(filename2));
        assertTrue(FileHelper.isFile(filename3));
        return directory;
    }

    @Test
    public void lastSlash1() {
        String input = "/";
        int expected = 0;
        int actual = FileHelper.lastSlash(input);
        assertEquals(expected, actual);
    }

    @Test
    public void lastSlash2() {
        String input = "\\";
        int expected = 0;
        int actual = FileHelper.lastSlash(input);
        assertEquals(expected, actual);
    }

    @Test
    public void lastSlash3() {
        String input = "123";
        int expected = -1;
        int actual = FileHelper.lastSlash(input);
        assertEquals(expected, actual);
    }

    @Test
    public void lastSlash4() {
        String input = "/123/567";
        int expected = 4;
        int actual = FileHelper.lastSlash(input);
        assertEquals(expected, actual);
    }

    @Test
    public void lastSlash5() {
        String input = "\\123\\567";
        int expected = 4;
        int actual = FileHelper.lastSlash(input);
        assertEquals(expected, actual);
    }

    @Test
    public void lastSlash6() {
        String input = "\\///\\///";
        int expected = 7;
        int actual = FileHelper.lastSlash(input);
        assertEquals(expected, actual);
    }

    @Test
    public void firstSlash1() {
        String input = "/";
        int expected = 0;
        int actual = FileHelper.firstSlash(input);
        assertEquals(expected, actual);
    }

    @Test
    public void firstSlash2() {
        String input = "\\/";
        int expected = 0;
        int actual = FileHelper.firstSlash(input);
        assertEquals(expected, actual);
    }

    @Test
    public void firstSlash3() {
        String input = "/\\";
        int expected = 0;
        int actual = FileHelper.firstSlash(input);
        assertEquals(expected, actual);
    }

    @Test
    public void firstSlash4() {
        String input = "foo/";
        int expected = 3;
        int actual = FileHelper.firstSlash(input);
        assertEquals(expected, actual);
    }

    @Test
    public void firstSlash5() {
        String input = "foo/bar/baz";
        int expected = 3;
        int actual = FileHelper.firstSlash(input);
        assertEquals(expected, actual);
    }

    @Test
    public void removeTrailingSlashWithSlashesWithoutSlashAtEnd() {
        String input = "c:/foo/bar/baz";
        String expected = input;
        String actual = FileHelper.removeTrailingSlash(input);
        assertEquals(expected, actual);
    }

    @Test
    public void removeTrailingSlashWithBackslashesWithoutSlashAtEnd() {
        String input = "c:\\foo\\bar\\baz";
        String expected = input;
        String actual = FileHelper.removeTrailingSlash(input);
        assertEquals(expected, actual);
    }

    @Test
    public void removeTrailingSlashWithSlashesWithSlashAtEnd() {
        String input = "c:/foo/bar/baz/";
        String expected = "c:/foo/bar/baz";
        String actual = FileHelper.removeTrailingSlash(input);
        assertEquals(expected, actual);
    }

    @Test
    public void removeTrailingSlashWithBackslashesWithSlashAtEnd() {
        String input = "c:\\foo\\bar\\baz\\";
        String expected = "c:\\foo\\bar\\baz";
        String actual = FileHelper.removeTrailingSlash(input);
        assertEquals(expected, actual);
    }

    @Test
    public void insertBeforeExtensionSimple() {
        String org = "foo.bar";
        String ins = FileHelper.insertBeforeExtension(org, "_baz");
        assertEquals("foo_baz.bar", ins);
    }

    @Test
    public void insertBeforeExtensionMoreDots() {
        String org = "foo.bar.baz";
        String ins = FileHelper.insertBeforeExtension(org, "_BAZ");
        assertEquals("foo.bar_BAZ.baz", ins);
    }

    @Test
    public void insertBeforeExtensionWithPath() {
        String org = "/users/justme/foo.bar.baz";
        String ins = FileHelper.insertBeforeExtension(org, "_BAZ");
        assertEquals("/users/justme/foo.bar_BAZ.baz", ins);
    }

    @Test
    public void insertBeforeExtensionWithPathAndEvenMoreDots() {
        String org = "/users.silly/./../just.me/foo.bar.baz.fooooobar";
        String ins = FileHelper.insertBeforeExtension(org, "_BAZ");
        assertEquals("/users.silly/./../just.me/foo.bar.baz_BAZ.fooooobar", ins);
    }

    @Test
    public void insertBeforeExtensionWithoutAnyDot() {
        String org = "foo_bar";
        String ins = FileHelper.insertBeforeExtension(org, "_baz");
        assertEquals("foo_bar_baz", ins);
    }

    @Test
    public void insertBeforeExtensionWithoutAnyDotButDotInPath() {
        String org = "/users.silly/./../just.me/foo_bar";
        String ins = FileHelper.insertBeforeExtension(org, "_baz");
        assertEquals("/users.silly/./../just.me/foo_bar_baz", ins);
    }

    @Test
    public void insertBeforeExtensionDotAtEnd() {
        String org = "foo.";
        String ins = FileHelper.insertBeforeExtension(org, "_baz");
        assertEquals("foo_baz.", ins);
    }

    @Test
    public void insertBeforeExtensionDotAtStart() {
        String org = ".foo";
        String ins = FileHelper.insertBeforeExtension(org, "_baz");
        assertEquals("_baz.foo", ins);
    }

    @Test
    public void insertBeforeExtensionDotAtStartWithPath() {
        String org = "/users.silly/./../just.me/.foo";
        String ins = FileHelper.insertBeforeExtension(org, "_baz");
        assertEquals("/users.silly/./../just.me/_baz.foo", ins);
    }

    @Test
    public void removeBeforeExtension() {
        String org = "/user/bla/datei_foo.txt";
        String ins = FileHelper.removeBeforeExtension(org, "_foo");
        assertEquals("/user/bla/datei.txt", ins);
    }

    @Test
    public void removeBeforeExtensionWithoutPath() {
        String org = "datei_foo.txt";
        String ins = FileHelper.removeBeforeExtension(org, "_foo");
        assertEquals("datei.txt", ins);
    }

    @Test (expected = IllegalArgumentException.class)
    public void failOnRemoveBeforeExtensionToRemoveNotInFilename() {
        String org = "datei_bar.txt";
        FileHelper.removeBeforeExtension(org, "_foo");
    }

    @Test (expected = IllegalArgumentException.class)
    public void failOnRemoveBeforeExtensionNoDorInFilename() {
        String org = "datei_foo_txt";
        FileHelper.removeBeforeExtension(org, "_foo");
    }

    @Test
    public void removeExtensionOnBareName() {
        String input = "bla.txt";
        String actual = FileHelper.removeExtension(input);
        String expected = "bla";
        assertEquals(expected, actual);
    }

    @Test
    public void removeExtensionOnFullName() {
        String input = "c:/foo/bar.txt";
        String actual = FileHelper.removeExtension(input);
        String expected = "c:/foo/bar";
        assertEquals(expected, actual);
    }

    @Test
    public void removeExtensionOnOnlyExtension() {
        String input = ".foo";
        String actual = FileHelper.removeExtension(input);
        String expected = "";
        assertEquals(expected, actual);
    }

    @Test
    public void removeExtensionOnOnlyExtensionWithPath() {
        String input = "/users.silly/./../just.me/.foo";
        String actual = FileHelper.removeExtension(input);
        String expected = "/users.silly/./../just.me/";
        assertEquals(expected, actual);
    }

    @Test
    public void removeExtensionWithoutExtension() {
        String input = "foo";
        String actual = FileHelper.removeExtension(input);
        String expected = "foo";
        assertEquals(expected, actual);
    }

    @Test
    public void removeAllFromLastUnderlineOnBareName() {
        String input = "bla_foo.txt";
        String actual = FileHelper.removeAllFromLastUnderline(input);
        String expected = "bla";
        assertEquals(expected, actual);
    }

    @Test
    public void removeAllFromLastUnderlineOnFullName() {
        String input = "c:/foo/bar_foo.txt";
        String actual = FileHelper.removeAllFromLastUnderline(input);
        String expected = "c:/foo/bar";
        assertEquals(expected, actual);
    }

    @Test
    public void removeAllFromLastUnderlineOnOnlySlash() {
        String input = "_foo";
        String actual = FileHelper.removeAllFromLastUnderline(input);
        String expected = "";
        assertEquals(expected, actual);
    }

    @Test
    public void removeAllFromLastUnderlineOnOnlySlashWithPath() {
        String input = "/users.silly/_/__/just_me/_foo";
        String actual = FileHelper.removeAllFromLastUnderline(input);
        String expected = "/users.silly/_/__/just_me/";
        assertEquals(expected, actual);
    }

    @Test
    public void removeAllFromLastUnderlineOnOnlySlashWithPathNoSlashInName() {
        String input = "/users.silly/_/__/just_me/foo";
        String actual = FileHelper.removeAllFromLastUnderline(input);
        String expected = "/users.silly/_/__/just";
        assertEquals(expected, actual);
    }

    @Test
    public void removeAllFromLastUnderlineWithoutSlash() {
        String input = "foo";
        String actual = FileHelper.removeAllFromLastUnderline(input);
        String expected = "foo";
        assertEquals(expected, actual);
    }

    @Test
    public void determineExtensionOnBareName() {
        String input = "bla.txt";
        String actual = FileHelper.determineExtension(input);
        String expected = ".txt";
        assertEquals(expected, actual);
    }

    @Test
    public void determineExtensionOnFullName() {
        String input = "c:/foo/bar.html";
        String actual = FileHelper.determineExtension(input);
        String expected = ".html";
        assertEquals(expected, actual);
    }

    @Test
    public void determineExtensionOnOnlyExtension() {
        String input = ".foo";
        String actual = FileHelper.determineExtension(input);
        String expected = ".foo";
        assertEquals(expected, actual);
    }

    @Test
    public void determineExtensionOnOnlyExtensionWithPath() {
        String input = "/users.silly/./../just.me/.foo";
        String actual = FileHelper.determineExtension(input);
        String expected = ".foo";
        assertEquals(expected, actual);
    }

    @Test
    public void determineExtensionWithoutExtension() {
        String input = "foo";
        String actual = FileHelper.determineExtension(input);
        String expected = FileHelper.NO_EXTENSION_FOUND;
        assertEquals(expected, actual);
    }

    @Test
    public void determineExtensionWithoutExtensionWithPath() {
        String input = "c:/foo/foo";
        String actual = FileHelper.determineExtension(input);
        String expected = FileHelper.NO_EXTENSION_FOUND;
        assertEquals(expected, actual);
    }

    @Test
    public void concatPathesNoSlash() {
        String part1 = "a/b/c";
        String part2 = "d/e/f";
        //String expected = "a/b/c/d/e/f"; // unix
        String expected = "a/b/c\\d/e/f"; // windows
        String actual = FileHelper.concatPathes(part1, part2);
        assertEquals(expected, actual);
    }

    @Test
    public void concatPathesSlashBehindFirst() {
        String part1 = "a/b/c/";
        String part2 = "d/e/f";
        String expected = "a/b/c/d/e/f";
        String actual = FileHelper.concatPathes(part1, part2);
        assertEquals(expected, actual);
    }

    @Test
    public void concatPathesSlashBeforeSecond() {
        String part1 = "a/b/c";
        String part2 = "/d/e/f";
        String expected = "a/b/c/d/e/f";
        String actual = FileHelper.concatPathes(part1, part2);
        assertEquals(expected, actual);
    }

    @Test
    public void concatPathesBothWithSlashes() {
        String part1 = "a/b/c/";
        String part2 = "/d/e/f";
        String expected = "a/b/c/d/e/f";
        String actual = FileHelper.concatPathes(part1, part2);
        assertEquals(expected, actual);
    }

    @Test
    public void concatPathesBothWithBackslashes() {
        String part1 = "a\\b\\c\\";
        String part2 = "\\d\\e\\f";
        String expected = "a\\b\\c\\d\\e\\f";
        String actual = FileHelper.concatPathes(part1, part2);
        assertEquals(expected, actual);
    }

    @Test
    public void concatPathesMultipleEmpty() {
        String expected = "";
        String actual = FileHelper.concatPathesMultiple();
        assertEquals(expected, actual);
    }

    @Test
    public void concatPathesMultipleOnePart() {
        String expected = "foo";
        String actual = FileHelper.concatPathesMultiple("foo");
        assertEquals(expected, actual);
    }

    @Test
    public void concatPathesMultipleTwoParts() {
        String expected = "foo\\bar";
        String actual = FileHelper.concatPathesMultiple("foo", "bar");
        assertEquals(expected, actual);
    }

    @Test
    public void concatPathesMultipleTwoPartsAndAnEmptyPartBetweenThem() {
        String expected = "foo\\bar";
        String actual = FileHelper.concatPathesMultiple("foo", "", "bar");
        assertEquals(expected, actual);
    }

    @Test
    public void concatPathesMultipleThreeParts() {
        String expected = "foo\\bar\\baz";
        String actual = FileHelper.concatPathesMultiple("foo", "bar", "baz");
        assertEquals(expected, actual);
    }

    @Test
    public void splitCsvSemikolonLine1() {
        String in = "\"DokNr\";\"Vortext\"";
        List<String> parts = FileHelper.splitCsvSemikolonLine(in);
        assertEquals(2, parts.size());
        assertEquals("DokNr", parts.get(0));
        assertEquals("Vortext", parts.get(1));
    }

    @Test
    public void normalizeToSlahes1() {
        String expected = "foo/bar/baz";
        String actual = FileHelper.normalizeToSlahes("foo\\bar\\baz");
        assertEquals(expected, actual);
    }

    @Test
    public void normalizeToSlahes2() {
        String expected = "foo/bar/baz";
        String actual = FileHelper.normalizeToSlahes("foo/bar/baz");
        assertEquals(expected, actual);
    }

    @Test
    public void normalizeToBackSlahes1() {
        String expected = "foo\\bar\\baz";
        String actual = FileHelper.normalizeToBackSlahes("foo\\bar\\baz");
        assertEquals(expected, actual);
    }

    @Test
    public void normalizeToBackSlahes2() {
        String expected = "foo\\bar\\baz";
        String actual = FileHelper.normalizeToBackSlahes("foo/bar/baz");
        assertEquals(expected, actual);
    }

    @Test
    public void splitPathWithSlashes() {
        List<String> parts = FileHelper.splitPath("c:/foo/bar/baz");
        assertEquals(4, parts.size());
        assertEquals("c:", parts.get(0));
        assertEquals("foo", parts.get(1));
        assertEquals("bar", parts.get(2));
        assertEquals("baz", parts.get(3));
    }

    @Test
    public void splitPathWithBackSlashes() {
        List<String> parts = FileHelper.splitPath("c:\\foo\\bar\\baz");
        assertEquals(4, parts.size());
        assertEquals("c:", parts.get(0));
        assertEquals("foo", parts.get(1));
        assertEquals("bar", parts.get(2));
        assertEquals("baz", parts.get(3));
    }

    @Test
    public void splitPathWithMixedSlashes() {
        List<String> parts = FileHelper.splitPath("c:/foo\\bar/baz");
        assertEquals(4, parts.size());
        assertEquals("c:", parts.get(0));
        assertEquals("foo", parts.get(1));
        assertEquals("bar", parts.get(2));
        assertEquals("baz", parts.get(3));
    }

    @Test
    public void getDirName() {
        String filename = "C:\\test\\README.txt";
        String actual = FileHelper.getDirName(filename);
        String expected = "C:\\test\\";
        assertEquals(expected, actual);
    }

    @Test
    public void getDirNameEndingWithDirAndBackslash() {
        String filename = "C:\\test\\foo\\";
        String actual = FileHelper.getDirName(filename);
        String expected = "C:\\test\\";
        assertEquals(expected, actual);
    }

    @Test
    public void getDirNameEndingWithDirAndSlash() {
        String filename = "C:/test/foo/";
        String actual = FileHelper.getDirName(filename);
        String expected = "C:/test/";
        assertEquals(expected, actual);
    }

    @Test
    public void getDirNameEndingWithDirWithoutBackSlash() {
        String filename = "C:\\test\\foo";
        String actual = FileHelper.getDirName(filename);
        String expected = "C:\\test\\";
        assertEquals(expected, actual);
    }

    @Test
    public void getDirNameEndingWithDirWithoutSlash() {
        String filename = "C:/test/foo";
        String actual = FileHelper.getDirName(filename);
        String expected = "C:/test/";
        assertEquals(expected, actual);
    }

    @Test
    public void getDirNameWithoutLastSlash() {
        String filename = "C:\\test\\README.txt";
        String actual = FileHelper.getDirNameWithoutLastSlash(filename);
        String expected = "C:\\test";
        assertEquals(expected, actual);
    }

    @Test
    public void getDirNameWithoutLastSlashEndingWithDirAndBackslash() {
        String filename = "C:\\test\\foo\\";
        String actual = FileHelper.getDirNameWithoutLastSlash(filename);
        String expected = "C:\\test";
        assertEquals(expected, actual);
    }

    @Test
    public void getDirNameWithoutLastSlashEndingWithDirWithoutBackslash() {
        String filename = "C:\\test\\foo";
        String actual = FileHelper.getDirNameWithoutLastSlash(filename);
        String expected = "C:\\test";
        assertEquals(expected, actual);
    }

    @Test
    public void getDirNameWithoutLastSlashEndingWithDirAndSlash() {
        String filename = "C:/test/foo/";
        String actual = FileHelper.getDirNameWithoutLastSlash(filename);
        String expected = "C:/test";
        assertEquals(expected, actual);
    }

    @Test
    public void getDirNameWithoutLastSlashEndingWithDirWithoutSlash() {
        String filename = "C:/test/foo";
        String actual = FileHelper.getDirNameWithoutLastSlash(filename);
        String expected = "C:/test";
        assertEquals(expected, actual);
    }

    @Test
    public void getDirNameWithoutLastSlashEndingWithDirWithoutAnySlash() {
        String filename = "C:";
        String actual = FileHelper.getDirNameWithoutLastSlash(filename);
        String expected = "";
        assertEquals(expected, actual);
    }

    @Test
    public void removeTrailingSlashOrBackslashWithSlash() {
        String filename = "C:/test/foo/";
        String actual = FileHelper.removeTrailingSlashOrBackslash(filename);
        String expected = "C:/test/foo";
        assertEquals(expected, actual);
    }

    @Test
    public void removeTrailingSlashOrBackslashWithBackslash() {
        String filename = "C:\\test\\foo\\";
        String actual = FileHelper.removeTrailingSlashOrBackslash(filename);
        String expected = "C:\\test\\foo";
        assertEquals(expected, actual);
    }

    @Test
    public void removeTrailingSlashOrBackslashWithoutAnySlash() {
        String filename = "C:\\test\\foo";
        String actual = FileHelper.removeTrailingSlashOrBackslash(filename);
        String expected = "C:\\test\\foo";
        assertEquals(expected, actual);
    }

    @Test
    public void removeTrailingSlashOrBackslashWithMultipeBackslash() {
        String filename = "C:\\test\\foo\\/";
        String actual = FileHelper.removeTrailingSlashOrBackslash(filename);
        String expected = "C:\\test\\foo\\";
        assertEquals(expected, actual);
    }

    @Test
    public void isDirectoryExisting() {
        String dir = "c:/temp";
        assertTrue(FileHelper.isDirectory(dir));
    }

    @Test
    public void isDirectoryNotExisting() {
        String dir = "! ;;; ::: not a existing, valid directory path ::: ;;; !";
        assertFalse(FileHelper.isDirectory(dir));
    }

    @Test
    public void isNotADirectoryExisting() {
        String dir = "c:/temp";
        assertFalse(FileHelper.isNotADirectory(dir));
    }

    @Test
    public void isNotADirectoryNotExisting() {
        String dir = "! ;;; ::: not a existing, valid directory path ::: ;;; !";
        assertTrue(FileHelper.isNotADirectory(dir));
    }

    @Test
    public void normalisePath() {
        String filename = "c:/tmp/../tmp/./foo.txt";
        String actual = FileHelper.normalisePath(filename);
        String expected = "C:\\tmp\\foo.txt";
        assertEquals(expected, actual);
    }

    @Test
    public void getSystemDisplayName() {
        String path = "C:\\";
        String actual = FileHelper.getSystemDisplayName(path);
        String expected = "Lokaler Datenträger";
        assertEquals(expected, actual);
    }

    @Test
    public void getSystemDisplayNameWithLowerDriveLetter() {
        String path = "c:\\";
        String actual = FileHelper.getSystemDisplayName(path);
        String expected = "Lokaler Datenträger";
        assertEquals(expected, actual);
    }

    @Test (expected = RuntimeException.class)
    public void getSystemDisplayNameFailOnWrongSlash() {
        String path = "C:/";
        FileHelper.getSystemDisplayName(path);
    }

    @Test (expected = RuntimeException.class)
    public void getSystemDisplayNameFailOnWrongPath() {
        String path = "\\\\Cluster1\\Projekte1\\";
        FileHelper.getSystemDisplayName(path);
    }

    @Test
    public void getSystemDisplayNameWithDeeperPath() {
        String path = "C:\\temp\\";
        String actual = FileHelper.getSystemDisplayName(path);
        String expected = "Lokaler Datenträger";
        assertEquals(expected, actual);
    }

    @Test
    public void getBareNameWithBackslashBehind() {
        String filename = "C:\\temp\\";
        String actual = FileHelper.getBareName(filename);
        String expected = "";
        assertEquals(expected, actual);
    }

    @Test
    public void getBareNameWithSlashBehind() {
        String filename = "C:/temp/";
        String actual = FileHelper.getBareName(filename);
        String expected = "";
        assertEquals(expected, actual);
    }

    @Test
    public void getBareName01() {
        String filename = "C:/temp/foo";
        String actual = FileHelper.getBareName(filename);
        String expected = "foo";
        assertEquals(expected, actual);
    }

    @Test
    public void getBareName02() {
        String filename = "C:/temp/foo/bar";
        String actual = FileHelper.getBareName(filename);
        String expected = "bar";
        assertEquals(expected, actual);
    }

    @Test
    public void getBareName03() {
        String filename = "C:/temp/foo/bar\\baz";
        String actual = FileHelper.getBareName(filename);
        String expected = "baz";
        assertEquals(expected, actual);
    }

    @Test
    public void getBareNameFromEmptyString() {
        String filename = "";
        String actual = FileHelper.getBareName(filename);
        String expected = "";
        assertEquals(expected, actual);
    }

    @Test
    public void buildFilenameFromPath01() {
        String path = "C:/temp/foo/bar\\baz";
        String actual = FileHelper.buildFilenameFromPath(path);
        String expected = "C_temp_foo_bar_baz";
        assertEquals(expected, actual);
    }

    @Test
    public void buildFilenameFromPath02() {
        String path = "\\\\Cluster1\\Projekte1\\Bla";
        String actual = FileHelper.buildFilenameFromPath(path);
        String expected = "Cluster1_Projekte1_Bla";
        assertEquals(expected, actual);
    }

    @Test
    public void fileSizeExisting() {
        String filename = path + "testfile1.txt";
        long actual = FileHelper.fileSize(filename);
        long expected = 24;
        assertEquals(expected, actual);
    }

    @Test
    public void fileSizeExistingWithFile() {
        File file = new File(path + "testfile1.txt");
        long actual = FileHelper.fileSize(file);
        long expected = 24;
        assertEquals(expected, actual);
    }

    @Test (expected = IORuntimeException.class)
    public void fileSizeFailureNotExisting() {
        String filename = "\\\\Cluster1\\Projekte1\\Bla";
        FileHelper.fileSize(filename);
    }

    @Test
    public void filesHaveEqualSizeTrue() {
        String filenameA = path + "testfile1.txt";
        String filenameB = path + "testfile1.txt";
        assertTrue(FileHelper.filesHaveEqualSize(filenameA, filenameB));
    }

    @Test
    public void filesHaveEqualSizeFalse() {
        String filenameA = path + "testfile1.txt";
        String filenameB = path + "file_writer_demo3.txt";
        assertFalse(FileHelper.filesHaveEqualSize(filenameA, filenameB));
    }

    @Test
    public void filesHaveEqualSizeWithFileTrue() {
        File fileA = new File(path + "testfile1.txt");
        File fileB = new File(path + "testfile1.txt");
        assertTrue(FileHelper.filesHaveEqualSize(fileA, fileB));
    }

    @Test
    public void filesHaveEqualSizeWithFileFalse() {
        File fileA = new File(path + "testfile1.txt");
        File fileB = new File(path + "file_writer_demo3.txt");
        assertFalse(FileHelper.filesHaveEqualSize(fileA, fileB));
    }

    @Test
    public void filesHaveSameLastModifiedTimeTrue() {
        String filenameA = path + "testfile1.txt";
        String filenameB = path + "testfile1.txt";
        assertTrue(FileHelper.filesHaveSameLastModifiedTime(filenameA, filenameB));
    }

    @Test
    public void filesHaveSameLastModifiedTimeFalse() {
        String filenameA = path + "testfile1.txt";
        String filenameB = path + "file_writer_demo3.txt";
        assertFalse(FileHelper.filesHaveSameLastModifiedTime(filenameA, filenameB));
    }

    @Test
    public void filesHaveSameLastModifiedTimeWithFileTrue() {
        File fileA = new File(path + "testfile1.txt");
        File fileB = new File(path + "testfile1.txt");
        assertTrue(FileHelper.filesHaveSameLastModifiedTime(fileA, fileB));
    }

    @Test
    public void filesHaveSameLastModifiedTimeWithFileFalse() {
        File fileA = new File(path + "testfile1.txt");
        File fileB = new File(path + "file_writer_demo3.txt");
        assertFalse(FileHelper.filesHaveSameLastModifiedTime(fileA, fileB));
    }

    @Test
    public void filesAreEqualEnoughTrue() {
        String filenameA = path + "testfile1.txt";
        String filenameB = path + "testfile1.txt";
        assertTrue(FileHelper.filesAreEqualEnough(filenameA, filenameB));
    }

    @Test
    public void filesAreEqualEnoughFalse() {
        String filenameA = path + "testfile1.txt";
        String filenameB = path + "file_writer_demo3.txt";
        assertFalse(FileHelper.filesAreEqualEnough(filenameA, filenameB));
    }

    @Test
    public void filesAreEqualEnoughWithFileTrue() {
        File fileA = new File(path + "testfile1.txt");
        File fileB = new File(path + "testfile1.txt");
        assertTrue(FileHelper.filesAreEqualEnough(fileA, fileB));
    }

    @Test
    public void filesAreEqualEnoughWithFileFalse() {
        File fileA = new File(path + "testfile1.txt");
        File fileB = new File(path + "file_writer_demo3.txt");
        assertFalse(FileHelper.filesAreEqualEnough(fileA, fileB));
    }

    @Test
    public void exchangeExtensionWithPathWithoutDotBeforeNewExtension() {
        String filename = "c:/temp/foo.txt";
        String actual = FileHelper.exchangeExtension(filename, "html");
        String expected = "c:/temp/foo.html";
        assertEquals(expected, actual);
    }

    @Test
    public void exchangeExtensionWithPathWithDotBeforeNewExtension() {
        String filename = "c:/temp/foo.txt";
        String actual = FileHelper.exchangeExtension(filename, ".html");
        String expected = "c:/temp/foo.html";
        assertEquals(expected, actual);
    }

    @Test
    public void exchangeExtensionWithPathWithoutDotBeforeNewExtensionMultipleDot() {
        String filename = "c:/temp/foo.bar.txt";
        String actual = FileHelper.exchangeExtension(filename, "html");
        String expected = "c:/temp/foo.bar.html";
        assertEquals(expected, actual);
    }

    @Test
    public void exchangeExtensionWithPathWithDotBeforeNewExtensionMultipleDot() {
        String filename = "c:/temp/foo.bar.txt";
        String actual = FileHelper.exchangeExtension(filename, ".html");
        String expected = "c:/temp/foo.bar.html";
        assertEquals(expected, actual);
    }

    @Test
    public void exchangeExtensionWithoutPathWithoutDotBeforeNewExtension() {
        String filename = "foo.txt";
        String actual = FileHelper.exchangeExtension(filename, "html");
        String expected = "foo.html";
        assertEquals(expected, actual);
    }

    @Test
    public void exchangeExtensionWithoutPathWithDotBeforeNewExtension() {
        String filename = "foo.txt";
        String actual = FileHelper.exchangeExtension(filename, ".html");
        String expected = "foo.html";
        assertEquals(expected, actual);
    }

    @Test
    public void exchangeExtensionWithoutPathWithoutDotBeforeNewExtensionMultipleDot() {
        String filename = "foo.bar.txt";
        String actual = FileHelper.exchangeExtension(filename, "html");
        String expected = "foo.bar.html";
        assertEquals(expected, actual);
    }

    @Test
    public void exchangeExtensionWithoutPathWithDotBeforeNewExtensionMultipleDot() {
        String filename = "foo.bar.txt";
        String actual = FileHelper.exchangeExtension(filename, ".html");
        String expected = "foo.bar.html";
        assertEquals(expected, actual);
    }

    @Test
    public void exchangeExtensionWithoutPathWithoutDotBeforeNewExtensionMultipleDotAndAtStart() {
        String filename = ".foo.bar.txt";
        String actual = FileHelper.exchangeExtension(filename, "html");
        String expected = ".foo.bar.html";
        assertEquals(expected, actual);
    }

    @Test
    public void exchangeExtensionWithoutPathWithDotBeforeNewExtensionMultipleDotAndAtStart() {
        String filename = ".foo.bar.txt";
        String actual = FileHelper.exchangeExtension(filename, ".html");
        String expected = ".foo.bar.html";
        assertEquals(expected, actual);
    }

    @Test
    public void exchangeExtensionWithoutPathWithDotBeforeNewExtensionMultipleDotAndAtStart7z() {
        String filename = ".foo.bar.7z";
        String actual = FileHelper.exchangeExtension(filename, ".txt");
        String expected = ".foo.bar.txt";
        assertEquals(expected, actual);
    }

    @Test (expected = IllegalArgumentException.class)
    public void exchangeExtensionFailesNoDot() {
        String filename = "hier ist kein Punkt!";
        FileHelper.exchangeExtension(filename, ".html");
    }

    @Test (expected = IllegalArgumentException.class)
    public void exchangeExtensionFailesOnlyDotAtStart() {
        String filename = ".foo";
        FileHelper.exchangeExtension(filename, ".html");
    }

    @Test (expected = IllegalArgumentException.class)
    public void exchangeExtensionFailesDotAtEnd() {
        String filename = "c:/temp/foo.bar.txt.";
        FileHelper.exchangeExtension(filename, ".html");
    }

    @Test (expected = IllegalArgumentException.class)
    public void exchangeExtensionFailesComplexExtension() {
        String filename = "c:/temp/foo.bar.übelübel";
        FileHelper.exchangeExtension(filename, ".html");
    }

    @Test (expected = IllegalArgumentException.class)
    public void exchangeExtensionFailesComplexExtension2() {
        String filename = "c:/temp/foo.bar,txt";
        FileHelper.exchangeExtension(filename, ".html");
    }

    @Test (expected = IllegalArgumentException.class)
    public void exchangeExtensionFailesComplexExtension3() {
        String filename = "c:/temp/foo.txt_so_nicht";
        FileHelper.exchangeExtension(filename, ".html");
    }

    @Test (expected = IllegalArgumentException.class)
    public void doNotExchangeAgainstSameExtension() {
        String filename = "c:/temp/foo.html";
        FileHelper.exchangeExtension(filename, ".html");
    }

    @Test
    public void replaceUncPathesR() {
        String filename = "\\\\Cluster1\\Projekte1\\HRTag\\HR_Strukt_HuP";
        String actual = FileHelper.replaceUncPathes(filename);
        String expected = "r:\\HRTag\\HR_Strukt_HuP";
        assertEquals(expected, actual);
    }

    @Test
    public void replaceUncPathesI1() {
        String filename = "\\\\Cluster2\\Projekte2\\Schufa\\Impressum";
        String actual = FileHelper.replaceUncPathes(filename);
        String expected = "i:";
        assertEquals(expected, actual);
    }

    @Test
    public void replaceUncPathesI2() {
        String filename = "\\\\Cluster2\\Projekte2\\Schufa\\Impressum\\data";
        String actual = FileHelper.replaceUncPathes(filename);
        String expected = "i:\\data";
        assertEquals(expected, actual);
    }

    @Test
    public void replaceUncPathesS() {
        String filename = "\\\\Cluster2\\Projekte2\\Schufa\\Mtest";
        String actual = FileHelper.replaceUncPathes(filename);
        String expected = "s:\\Schufa\\Mtest";
        assertEquals(expected, actual);
    }

    @Test
    public void replaceUncPathesUBig() {
        String filename = "\\\\Cluster1\\User1\\CD\\ImpressumProjekt";
        String actual = FileHelper.replaceUncPathes(filename);
        String expected = "u:\\ImpressumProjekt";
        assertEquals(expected, actual);
    }

    @Test
    public void replaceUncPathesUSmall() {
        String filename = "\\\\Cluster1\\user1\\CD\\ImpressumProjekt";
        String actual = FileHelper.replaceUncPathes(filename);
        String expected = "u:\\ImpressumProjekt";
        assertEquals(expected, actual);
    }

    @Test
    public void findFilesInMainDirectoryFindOneDotHtmlFile() {
        String dir = path + "findFilesInMainDirectoryNio2";
        String extension = ".html";
        List<String> files = FileHelper.findFilesInMainDirectory(dir, extension);
        assertEquals(1, files.size());
        assertEquals(dir + "\\test1.html", files.get(0));
    }

    @Test
    public void findFilesInMainDirectoryFindOneHtmlFile() {
        String dir = path + "findFilesInMainDirectoryNio2";
        String extension = "html";
        List<String> files = FileHelper.findFilesInMainDirectory(dir, extension);
        assertEquals(1, files.size());
        assertEquals(dir + "\\test1.html", files.get(0));
    }

    @Test
    public void findFilesInMainDirectoryFindTwoDotTextFiles() {
        String dir = path + "findFilesInMainDirectoryNio2";
        String extension = ".txt";
        List<String> files = FileHelper.findFilesInMainDirectory(dir, extension);
        assertEquals(2, files.size());
        assertEquals(dir + "\\test2.txt", files.get(0));
        assertEquals(dir + "\\test3.txt", files.get(1));
    }

    @Test
    public void findFilesInMainDirectoryFindTwoTextFilese() {
        String dir = path + "findFilesInMainDirectoryNio2";
        String extension = "txt";
        List<String> files = FileHelper.findFilesInMainDirectory(dir, extension);
        assertEquals(2, files.size());
        assertEquals(dir + "\\test2.txt", files.get(0));
        assertEquals(dir + "\\test3.txt", files.get(1));
    }

    @Test
    public void findFilesInMainDirectoryFindOneDotHtmlFileNio2() {
        String dir = path + "findFilesInMainDirectoryNio2";
        String extension = ".html";
        List<String> files = FileHelper.findFilesInMainDirectoryNio2WithExtensions(dir, extension);
        assertEquals(1, files.size());
        assertEquals(dir + "\\test1.html", files.get(0));
    }

    @Test
    public void findFilesInMainDirectoryFindOneHtmlFileNio2() {
        String dir = path + "findFilesInMainDirectoryNio2";
        String extension = "html";
        List<String> files = FileHelper.findFilesInMainDirectoryNio2WithExtensions(dir, extension);
        assertEquals(1, files.size());
        assertEquals(dir + "\\test1.html", files.get(0));
    }

    @Test
    public void findFilesInMainDirectoryFindTwoDotTextFilesNio2() {
        String dir = path + "findFilesInMainDirectoryNio2";
        String extension = ".txt";
        List<String> files = FileHelper.findFilesInMainDirectoryNio2WithExtensions(dir, extension);
        assertEquals(2, files.size());
        assertEquals(dir + "\\test2.txt", files.get(0));
        assertEquals(dir + "\\test3.txt", files.get(1));
    }

    @Test
    public void findFilesInMainDirectoryFindTwoTextFilesNio2() {
        String dir = path + "findFilesInMainDirectoryNio2";
        String extension = "txt";
        List<String> files = FileHelper.findFilesInMainDirectoryNio2WithExtensions(dir, extension);
        assertEquals(2, files.size());
        assertEquals(dir + "\\test2.txt", files.get(0));
        assertEquals(dir + "\\test3.txt", files.get(1));
    }

    @Test
    public void findFilesInMainDirectoryFindOneHtmlAndTwoTextFilesNio2() {
        String dir = path + "findFilesInMainDirectoryNio2";
        String extension1 = "txt";
        String extension2 = "html";
        List<String> files = FileHelper.findFilesInMainDirectoryNio2WithExtensions(dir, extension1,
                extension2);
        assertEquals(3, files.size());
        assertEquals(dir + "\\test2.txt", files.get(0));
        assertEquals(dir + "\\test3.txt", files.get(1));
        assertEquals(dir + "\\test1.html", files.get(2));
    }

    @Test
    public void findFilesInMainDirectoryNio2StartsWith() {
        String dir = path + "findFilesInMainDirectoryNio2";
        String start = "test";
        List<String> files = FileHelper.findFilesInMainDirectoryNio2StartsWith(dir, start);
        assertEquals(3, files.size());
        assertEquals(dir + "\\test1.html", files.get(0));
        assertEquals(dir + "\\test2.txt", files.get(1));
        assertEquals(dir + "\\test3.txt", files.get(2));
    }

    @Test
    public void findFilesInMainDirectoryNio2EndsWith() {
        String dir = path + "findFilesInMainDirectoryNio2\\subdir";
        String end = "_dump\\.zip";
        List<String> files = FileHelper.findFilesInMainDirectoryNio2EndsWith(dir, end);
        assertEquals(1, files.size());
        assertEquals(dir + "\\wiki_backup_20210607_142843_dump.zip", files.get(0));
    }

    @Test
    public void findFilesNio2EndsWith() {
        String dir = path + "findFilesInMainDirectoryNio2";
        String end = "_dump\\.zip";
        List<String> files = FileHelper.findFilesNio2EndsWith(dir, end);
        assertEquals(2, files.size());
        assertEquals(dir + "\\subdir\\wiki_backup_20210607_142843_dump.zip", files.get(0));
        assertEquals(dir + "\\subdir2\\wiki_backup_20210604_120051_dump.zip", files.get(1));
    }

    @Test
    public void containsFiles() {
        String dir = path + "findFilesInMainDirectoryNio2";
        String extension = "txt";
        boolean found = FileHelper.containsFiles(dir, extension);
        assertTrue(found);
    }

    @Test
    public void containsFilesWithDot() {
        String dir = path + "findFilesInMainDirectoryNio2";
        String extension = ".txt";
        boolean found = FileHelper.containsFiles(dir, extension);
        assertTrue(found);
    }

    @Test
    public void findAllFilesInMainDirectory() {
        String dir = path + "findFilesInMainDirectoryNio2";
        List<String> files = FileHelper.findAllFilesInMainDirectory(dir);
        assertEquals(3, files.size());
        assertEquals(dir + "\\test1.html", files.get(0));
        assertEquals(dir + "\\test2.txt", files.get(1));
        assertEquals(dir + "\\test3.txt", files.get(2));
    }

    @Test
    public void findAllFilesInMainDirectoryNio2() {
        String dir = path + "findFilesInMainDirectoryNio2";
        List<String> files = FileHelper.findAllFilesInMainDirectoryNio2(dir);
        assertEquals(3, files.size());
        assertEquals(dir + "\\test1.html", files.get(0));
        assertEquals(dir + "\\test2.txt", files.get(1));
        assertEquals(dir + "\\test3.txt", files.get(2));
    }

    @Test
    public void findFiles() {
        String dir = path + "findFilesInMainDirectoryNio2";
        List<String> files = FileHelper.findFiles(dir, ".htm", ".html", ".txt");
        assertEquals(5, files.size());
        assertEquals(dir + "\\subdir\\test1.html", files.get(0));
        assertEquals(dir + "\\subdir\\test2.txt", files.get(1));
        assertEquals(dir + "\\test1.html", files.get(2));
        assertEquals(dir + "\\test2.txt", files.get(3));
        assertEquals(dir + "\\test3.txt", files.get(4));
    }

    @Test
    public void findFilesNio2() {
        String dir = path + "findFilesInMainDirectoryNio2";
        List<String> files = FileHelper.findFilesNio2(dir, ".htm", ".html", ".txt");
        //for (String file : files)  System.out.println(file);
        assertEquals(5, files.size());
        assertEquals(dir + "\\subdir\\test1.html", files.get(0));
        assertEquals(dir + "\\subdir\\test2.txt", files.get(1));
        assertEquals(dir + "\\test1.html", files.get(2));
        assertEquals(dir + "\\test2.txt", files.get(3));
        assertEquals(dir + "\\test3.txt", files.get(4));
    }

    @Test
    public void findFilesNio2UpperCaseExtension() {
        String dir = path + "findFilesInMainDirectoryNio2";
        List<String> files = FileHelper.findFilesNio2(dir, "HTML", "TXT");
        assertEquals(5, files.size());
        assertEquals(dir + "\\subdir\\test1.html", files.get(0));
        assertEquals(dir + "\\subdir\\test2.txt", files.get(1));
        assertEquals(dir + "\\test1.html", files.get(2));
        assertEquals(dir + "\\test2.txt", files.get(3));
        assertEquals(dir + "\\test3.txt", files.get(4));
    }

    @Test
    public void findFilesNio2Old() {
        String dir = path + "findFilesInMainDirectoryNio2";
        List<String> files = FileHelper.findFilesNio2Old(dir, ".htm", ".html", ".txt");
        assertEquals(5, files.size());
        assertEquals(dir + "\\subdir\\test1.html", files.get(0));
        assertEquals(dir + "\\subdir\\test2.txt", files.get(1));
        assertEquals(dir + "\\test1.html", files.get(2));
        assertEquals(dir + "\\test2.txt", files.get(3));
        assertEquals(dir + "\\test3.txt", files.get(4));
    }

    @Test
    public void findFilesNio2OldUpperCaseExtension() {
        String dir = path + "findFilesInMainDirectoryNio2";
        List<String> files = FileHelper.findFilesNio2Old(dir, "HTML", "TXT");
        assertEquals(5, files.size());
        assertEquals(dir + "\\subdir\\test1.html", files.get(0));
        assertEquals(dir + "\\subdir\\test2.txt", files.get(1));
        assertEquals(dir + "\\test1.html", files.get(2));
        assertEquals(dir + "\\test2.txt", files.get(3));
        assertEquals(dir + "\\test3.txt", files.get(4));
    }

    @Test
    public void findAllFilesNio2() {
        String dir = path + "findFilesInMainDirectoryNio2";
        List<String> files = FileHelper.findAllFilesNio2(dir);
        assertEquals(7, files.size());
        assertEquals(dir + "\\subdir\\test1.html", files.get(0));
        assertEquals(dir + "\\subdir\\test2.txt", files.get(1));
        assertEquals(dir + "\\subdir\\wiki_backup_20210607_142843_dump.zip", files.get(2));
        assertEquals(dir + "\\subdir2\\wiki_backup_20210604_120051_dump.zip", files.get(3));
        assertEquals(dir + "\\test1.html", files.get(4));
        assertEquals(dir + "\\test2.txt", files.get(5));
        assertEquals(dir + "\\test3.txt", files.get(6));
    }

    @Test
    public void findAllDirectoriesNio2() {
        String dir = path + "findFilesInMainDirectoryNio2";
        List<String> files = FileHelper.findAllDirectoriesNio2(dir);
        assertEquals(2, files.size());
        assertEquals(dir + "\\subdir", files.get(0));
        assertEquals(dir + "\\subdir2", files.get(1));
    }

    @Test
    public void createDirectoryWithMissingSubdirectoriesIfNotExists() {
        prepareForCreatingSubdirectories();

        String dir = FileHelper.concatPathesMultiple(multipeSubsDir, "sub1", "sub2", "sub3");
        //System.out.println(dir);
        assertFalse(FileHelper.isDirectory(dir));
        FileHelper.createDirectoryWithMissingSubdirectoriesIfNotExists(dir);
        assertTrue(FileHelper.isDirectory(dir));

        removeForCreatingSubdirectories();
    }

    @Test
    public void createMissingDirectoriesForFile() {
        prepareForCreatingSubdirectories();


        String filename = FileHelper.concatPathesMultiple(multipeSubsDir, "sub1", "sub2", "sub3",
                "hallo.txt");
        //System.out.println(filename);
        assertFalse(FileHelper.isFile(filename));
        FileHelper.createMissingDirectoriesForFile(filename);
        FileHelper.writeTextToFile("Hallo!", filename);
        assertTrue(FileHelper.isFile(filename));

        removeForCreatingSubdirectories();
    }

    private void prepareForCreatingSubdirectories() {
        assertTrue(FileHelper.isDirectory(path));
        assertFalse(FileHelper.isDirectory(multipeSubsDir));
    }

    private void removeForCreatingSubdirectories() {
        FileHelper.deleteTree(multipeSubsDir);

        assertTrue(FileHelper.isDirectory(path));
        assertFalse(FileHelper.isDirectory(multipeSubsDir));
    }

    @Test
    public void determineAllFilesInMainDirectoryDescendingByTime() {
        // path = C:\Users\Anwender\Daten\java\workspace\de.duehl.basics\data\testfiles\
        String dir = FileHelper.concatPathes(path, "fixed_times");

        List<FileWithModificationTime> files =
                FileHelper.determineAllFilesInMainDirectoryDescendingByTime(dir);

        assertEquals(9, files.size());

        assertEquals(dir + "\\example.html", files.get(0).getFilename());
        assertEquals(dir + "\\file_writer_demo.txt", files.get(1).getFilename());
        assertEquals(dir + "\\file_writer_demo2.txt", files.get(2).getFilename());
        assertEquals(dir + "\\file_writer_demo3.txt", files.get(3).getFilename());
        assertEquals(dir + "\\file_writer_demo_write_fields.txt", files.get(4).getFilename());
        assertEquals(dir + "\\file_writer_demo_write_fields_list.txt", files.get(5).getFilename());
        assertEquals(dir + "\\file_writer_demo_write_fields_vararg.txt", files.get(6).getFilename());
        assertEquals(dir + "\\example.txt", files.get(7).getFilename());
        assertEquals(dir + "\\testfile1.txt", files.get(8).getFilename());

        assertEquals("20190124_121035", files.get(0).getModificationTime());
        assertEquals("20190118_094601", files.get(1).getModificationTime());
        assertEquals("20190118_094601", files.get(2).getModificationTime());
        assertEquals("20190118_094601", files.get(3).getModificationTime());
        assertEquals("20190118_094601", files.get(4).getModificationTime());
        assertEquals("20190118_094601", files.get(5).getModificationTime());
        assertEquals("20190118_094601", files.get(6).getModificationTime());
        assertEquals("20180824_131948", files.get(7).getModificationTime());
        assertEquals("20140330_124526", files.get(8).getModificationTime());
    }

    @Test
    public void prepareToFilenamePartEmptyString() {
        String complexSearch = "";
        String actual = FileHelper.prepareToFilenamePart(complexSearch);
        String expected = "";
        assertEquals(expected, actual);
    }

    @Test
    public void prepareToFilenamePartThreeUndescores() {
        String complexSearch = "___";
        String actual = FileHelper.prepareToFilenamePart(complexSearch);
        String expected = "";
        assertEquals(expected, actual);
    }

    @Test
    public void prepareToFilenamePartRealInput() {
        String complexSearch = "name:Heins AND strasse:Decius*";
        String actual = FileHelper.prepareToFilenamePart(complexSearch);
        String expected = "name_Heins_AND_strasse_Decius";
        assertEquals(expected, actual);
    }

    @Test
    public void prepareToFilenamePartRealInputWithSpaces() {
        String complexSearch = "          name:Heins    AND   strasse:Decius*    ";
        String actual = FileHelper.prepareToFilenamePart(complexSearch);
        String expected = "name_Heins_AND_strasse_Decius";
        assertEquals(expected, actual);
    }

    @Test
    public void readFirstLineStartingWith() {
        String filename = path + "DictionaryTestFile.txt";
        Charset charset = Charset.UTF_8;
        String lineStart = "Englisch";

        String actual = FileHelper.readFirstLineStartingWith(filename, charset, lineStart);
        String expected = "Englisches Wort";
        assertEquals(expected, actual);
    }

    @Test
    public void copyFirstNLinesOfTextFile() {
        String filename = path + "DictionaryTestFile.txt";
        Charset charset = Charset.UTF_8;

        String filenameOut = path + "DictionaryTestFile_erste_12_Zeilen.txt";
        FileHelper.copyFirstNLinesOfTextFile(filename, filenameOut, charset, 12);

        List<String> allLines = FileHelper.readFileToList(filename, charset);
        List<String> firstLines = FileHelper.readFileToList(filenameOut, charset);

        assertEquals(18, allLines.size());
        assertEquals(12, firstLines.size());

        for (int index = 0; index < firstLines.size(); ++index) {
            String expected = allLines.get(index);
            String actual = firstLines.get(index);
            assertEquals(expected, actual);
        }
    }

    @Test
    public void emptyDirectoryIsEmpty() {
        String emptyDirectory = FileHelper.concatPathes(path, "emptyDirectory");
        assertTrue(FileHelper.isEmptyDirectory(emptyDirectory));
        assertTrue(FileHelper.isDirectoryEmpty(emptyDirectory));
    }

    @Test
    public void notExistingDirectoryIsNotEmpty() {
        String emptyDirectory = FileHelper.concatPathes(path, "notExistingDirectory");
        assertFalse(FileHelper.isEmptyDirectory(emptyDirectory));
    }

    @Test (expected = NullPointerException.class)
    public void notExistingDirectoryCrashes() {
        String emptyDirectory = FileHelper.concatPathes(path, "notExistingDirectory");
        assertFalse(FileHelper.isDirectoryEmpty(emptyDirectory));
    }

    @Test
    public void notEmptyDirectoryIsNotEmpty() {
        String notEmptyDirectory = path;
        assertFalse(FileHelper.isEmptyDirectory(notEmptyDirectory));
        assertFalse(FileHelper.isDirectoryEmpty(notEmptyDirectory));
    }

    @Test
    public void emptyFileIsEmpty() {
        String emptyFile = FileHelper.concatPathes(path, "emptyFile");
        assertTrue(FileHelper.isEmptyFile(emptyFile));
        assertTrue(FileHelper.isFileEmpty(emptyFile));
    }

    @Test
    public void notExistingFileIsNotEmpty() {
        String emptyFile = FileHelper.concatPathes(path, "notExistingFile");
        assertFalse(FileHelper.isEmptyFile(emptyFile));
    }

    @Test (expected = IORuntimeException.class)
    public void notExistingFileCrashes() {
        String emptyFile = FileHelper.concatPathes(path, "notExistingFile");
        assertFalse(FileHelper.isFileEmpty(emptyFile));
    }

    @Test
    public void notEmptyFileIsNotEmpty() {
        String notEmptyFile = FileHelper.concatPathes(path, "example.txt");
        assertFalse(FileHelper.isEmptyFile(notEmptyFile));
        assertFalse(FileHelper.isFileEmpty(notEmptyFile));
    }

    @Test
    public void replaceForbiddenFilenameCharacters() {
        String filenamePart = "Dieser \"String\" enthält unerwünschte Zeichen: *, <, >, |, /, \\";
        String actual = FileHelper.replaceForbiddenFilenameCharacters(filenamePart, "_");
        String expected = "Dieser _String_ enthält unerwünschte Zeichen_ _, _, _, _, _, _";
        assertEquals(expected, actual);
    }

    @Test
    public void replaceForbiddenFilenameCharactersEmptyInput() {
        String filenamePart = "";
        String actual = FileHelper.replaceForbiddenFilenameCharacters(filenamePart, "_");
        String expected = "";
        assertEquals(expected, actual);
    }

    @Test
    public void replaceForbiddenFilenameCharactersDelete() {
        String filenamePart = "Dieser \"String\" enthält unerwünschte Zeichen: *, <, >, |, /, \\";
        String actual = FileHelper.replaceForbiddenFilenameCharacters(filenamePart, "");
        String expected = "Dieser String enthält unerwünschte Zeichen , , , , , ";
        assertEquals(expected, actual);
    }

    @Test
    public void isBareFilenameEmpty() {
        String filename = "";
        assertTrue(FileHelper.isBareFilename(filename));
    }

    @Test
    public void isBareFilenameNormal() {
        String filename = "foo.txt";
        assertTrue(FileHelper.isBareFilename(filename));
    }

    @Test
    public void isBareFilenamePathWithSlashes() {
        String filename = "c:/temp/foo.txt";
        assertFalse(FileHelper.isBareFilename(filename));
    }

    @Test
    public void isBareFilenamePathWithBackslashes() {
        String filename = "c:\\temp\\foo.txt";
        assertFalse(FileHelper.isBareFilename(filename));
    }

    @Test
    public void getFilesWithGivenBareFilenameEmptyBareFilenameFromEmptyList() {
        List<String> filenames = CollectionsHelper.buildListFrom();
        String bareFilename = "";

        List<String> actualList = FileHelper.getFilesWithGivenBareFilename(filenames, bareFilename);
        List<String> expectedList = CollectionsHelper.buildListFrom();

        assertEquals(expectedList, actualList);
    }

    @Test
    public void getFilesWithGivenBareFilenameEmptyBareFilenameFromNotEmptyList() {
        List<String> filenames = CollectionsHelper.buildListFrom("C:\\foo.txt");
        String bareFilename = "";

        List<String> actualList = FileHelper.getFilesWithGivenBareFilename(filenames, bareFilename);
        List<String> expectedList = CollectionsHelper.buildListFrom();

        assertEquals(expectedList, actualList);
    }

    @Test
    public void getFilesWithGivenBareFilenameEmptyBareFilenameFromNotEmptyListWithDir() {
        List<String> filenames = CollectionsHelper.buildListFrom("C:\\foo.txt", "C:\\");
        String bareFilename = "";

        List<String> actualList = FileHelper.getFilesWithGivenBareFilename(filenames, bareFilename);
        List<String> expectedList = CollectionsHelper.buildListFrom("C:\\");
        // fraglich ob man das will.... ggf. leeren bareFilename abfangen.

        assertEquals(expectedList, actualList);
    }

    @Test
    public void getFilesWithGivenBareFilenameNotContainedBareFilename() {
        List<String> filenames = CollectionsHelper.buildListFrom("C:\\foo.txt");
        String bareFilename = "bar.txt";

        List<String> actualList = FileHelper.getFilesWithGivenBareFilename(filenames, bareFilename);
        List<String> expectedList = CollectionsHelper.buildListFrom();

        assertEquals(expectedList, actualList);
    }

    @Test
    public void getFilesWithGivenBareFilenameContainedBareFilenameInListWithOneFile() {
        List<String> filenames = CollectionsHelper.buildListFrom("C:\\foo.txt");
        String bareFilename = "foo.txt";

        List<String> actualList = FileHelper.getFilesWithGivenBareFilename(filenames, bareFilename);
        List<String> expectedList = CollectionsHelper.buildListFrom("C:\\foo.txt");

        assertEquals(expectedList, actualList);
    }

    @Test
    public void getFilesWithGivenBareFilename01() {
        List<String> filenames = CollectionsHelper.buildListFrom("C:\\foo.txt", "C:\\bar.txt",
                "C:\\foo\\foo.txt", "C:\\bar\\baz\\foo.txt", "D:\\baz.txt");
        String bareFilename = "foo.txt";

        List<String> actualList = FileHelper.getFilesWithGivenBareFilename(filenames, bareFilename);
        List<String> expectedList = CollectionsHelper.buildListFrom("C:\\foo.txt",
                "C:\\foo\\foo.txt", "C:\\bar\\baz\\foo.txt");

        assertEquals(expectedList, actualList);
    }

    @Test
    public void getFilesWithGivenExtensionInMixedList() {
        List<String> filenames = CollectionsHelper.buildListFrom("C:\\foo.pdf", "C:\\bar.txt",
                "C:\\foo\\foo.txt", "C:\\bar\\baz\\foo.txt", "D:\\baz.pdf");
        String extension = ".pdf";

        List<String> actualList = FileHelper.getFilesWithGivenExtension(filenames, extension);
        List<String> expectedList = CollectionsHelper.buildListFrom("C:\\foo.pdf", "D:\\baz.pdf");

        assertEquals(expectedList, actualList);
    }

    @Test
    public void getFilesWithGivenExtensionWithoutPointInMixedList() {
        List<String> filenames = CollectionsHelper.buildListFrom("C:\\foo.pdf", "C:\\bar.txt",
                "C:\\foo\\foo.txt", "C:\\bar\\baz\\foo.txt", "D:\\baz.pdf");
        String extension = "pdf";

        List<String> actualList = FileHelper.getFilesWithGivenExtension(filenames, extension);
        List<String> expectedList = CollectionsHelper.buildListFrom("C:\\foo.pdf", "D:\\baz.pdf");

        assertEquals(expectedList, actualList);
    }

    @Test
    public void getFilesWithGivenExtensionInEmptyList() {
        List<String> filenames = CollectionsHelper.buildListFrom();
        String extension = ".txt";

        List<String> actualList = FileHelper.getFilesWithGivenExtension(filenames, extension);
        List<String> expectedList = CollectionsHelper.buildListFrom();

        assertEquals(expectedList, actualList);
    }

    @Test
    public void getFilesWithGivenExtensionInListWithoutWantedExtension() {
        List<String> filenames = CollectionsHelper.buildListFrom("C:\\foo.pdf", "D:\\baz.pdf");
        String extension = ".txt";

        List<String> actualList = FileHelper.getFilesWithGivenExtension(filenames, extension);
        List<String> expectedList = CollectionsHelper.buildListFrom();

        assertEquals(expectedList, actualList);
    }

    @Test
    public void filenamesToBareFilenames() {
        List<String> filenames = CollectionsHelper.buildListFrom("C:\\foo.pdf", "D:\\baz.pdf");
        List<String> bareFilenames = FileHelper.filenamesToBareFilenames(filenames);
        assertEquals(2, bareFilenames.size());
        assertEquals("foo.pdf", bareFilenames.get(0));
        assertEquals("baz.pdf", bareFilenames.get(1));
    }

    @Test
    public void endsWithExtensionsSuccessWithSmallMp3() {
        String filename = "c:\\a\\b\\c\\d\\xyz.mp3";
        String extension = ".mp3";
        assertTrue(FileHelper.endsWithExtension(filename, extension));
    }

    @Test
    public void endsWithExtensionsSuccessWithBigMp3() {
        String filename = "c:\\a\\b\\c\\d\\xyz.MP3";
        String extension = ".mp3";
        assertTrue(FileHelper.endsWithExtension(filename, extension));
    }

    @Test
    public void endsWithOneOfMultipleExtensionsSuccessWithSmallMp3() {
        String filename = "c:\\a\\b\\c\\d\\xyz.mp3";
        List<String> extensions = CollectionsHelper.buildListFrom(".mp3", ".m4a");
        assertTrue(FileHelper.endsWithOneOfMultipleExtensions(filename, extensions));
    }

    @Test
    public void endsWithOneOfMultipleExtensionsSuccessWithBigMp3() {
        String filename = "c:\\a\\b\\c\\d\\xyz.MP3";
        List<String> extensions = CollectionsHelper.buildListFrom(".mp3", ".m4a");
        assertTrue(FileHelper.endsWithOneOfMultipleExtensions(filename, extensions));
    }

    @Test
    public void endsWithOneOfMultipleExtensionsNoSuceess() {
        String filename = "c:\\a\\b\\c\\d\\xyz.txt";
        List<String> extensions = CollectionsHelper.buildListFrom(".mp3", ".m4a");
        assertFalse(FileHelper.endsWithOneOfMultipleExtensions(filename, extensions));
    }

    @Test
    public void commandStartsWithExistingFilenameExisting() {
        String command = "C:\\Windows\\explorer.exe foo bla";
        assertTrue(FileHelper.commandStartsWithExistingFilename(command));
    }

    @Test
    public void commandStartsWithExistingFilenameNotExisting() {
        String command = "c:\\a\\b\\c\\d\\xyz.txt foo bla";
        assertFalse(FileHelper.commandStartsWithExistingFilename(command));
    }

    @Test
    public void commandStartsWithExistingFilenameEmptyString() {
        String command = "";
        assertFalse(FileHelper.commandStartsWithExistingFilename(command));
    }

    @Test
    public void commandStartsWithExistingFilenameStartsWithBlank() {
        String command = " foo bla";
        assertFalse(FileHelper.commandStartsWithExistingFilename(command));
    }

    @Test (expected = RuntimeException.class)
    public void findTheOneFileInMainDirectoryNoFile() {
        String bareNameStart = "b_";
        String bareNameEnd = ".txt";
        FileHelper.findTheOneFileInMainDirectory(theOneFileDir, bareNameStart, bareNameEnd);
    }

    @Test
    public void findTheOneFileInMainDirectoryOneFile() {
        String bareNameStart = "a_2";
        String bareNameEnd = ".txt";
        String bareFilename = FileHelper.findTheOneFileInMainDirectory(theOneFileDir, bareNameStart,
                bareNameEnd);
        assertEquals("a_2.txt", bareFilename);
    }

    @Test (expected = RuntimeException.class)
    public void findTheOneFileInMainDirectoryTwoFile() {
        String bareNameStart = "a_1_";
        String bareNameEnd = ".txt";
        FileHelper.findTheOneFileInMainDirectory(theOneFileDir, bareNameStart, bareNameEnd);
    }


    // theOneFileDir
}
