/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.io.filefilter;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assumptions.assumeTrue;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOCase;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.file.PathUtils;
import org.apache.commons.io.file.TempFile;
import org.apache.commons.io.test.TestUtils;
import org.apache.commons.lang3.SystemUtils;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertNull;

/**
 * Used to test FileFilterUtils.
 */
public class FileFilterTest extends AbstractFilterTest {

    @Test
    public void testAgeFilter() throws Exception {
        final File oldFile = new File(temporaryFolder, "old.txt");
        final Path oldPath = oldFile.toPath();
        final File reference = new File(temporaryFolder, "reference.txt");
        final File newFile = new File(temporaryFolder, "new.txt");
        final Path newPath = newFile.toPath();

        if (!oldFile.getParentFile().exists()) {
            fail("Cannot create file " + oldFile + " as the parent directory does not exist");
        }
        try (BufferedOutputStream output1 = new BufferedOutputStream(Files.newOutputStream(oldFile.toPath()))) {
            TestUtils.generateTestData(output1, 0);
        }

        do {
            try {
                TestUtils.sleep(1000);
            } catch (final InterruptedException ie) {
                // ignore
            }
            if (!reference.getParentFile().exists()) {
                fail("Cannot create file " + reference + " as the parent directory does not exist");
            }
            try (BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(reference.toPath()))) {
                TestUtils.generateTestData(output, 0);
            }
        } while (equalsLastModified(oldFile, reference));

        final Date date = new Date();
        final long now = date.getTime();

        do {
            try {
                TestUtils.sleep(1000);
            } catch (final InterruptedException ie) {
                // ignore
            }
            if (!newFile.getParentFile().exists()) {
                fail("Cannot create file " + newFile + " as the parent directory does not exist");
            }
            try (BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(newFile.toPath()))) {
                TestUtils.generateTestData(output, 0);
            }
        } while (equalsLastModified(reference, newFile));

        final IOFileFilter filter1 = FileFilterUtils.ageFileFilter(now);
        final IOFileFilter filter2 = FileFilterUtils.ageFileFilter(now, true);
        final IOFileFilter filter3 = FileFilterUtils.ageFileFilter(now, false);
        final IOFileFilter filter4 = FileFilterUtils.ageFileFilter(date);
        final IOFileFilter filter5 = FileFilterUtils.ageFileFilter(date, true);
        final IOFileFilter filter6 = FileFilterUtils.ageFileFilter(date, false);
        final IOFileFilter filter7 = FileFilterUtils.ageFileFilter(reference);
        final IOFileFilter filter8 = FileFilterUtils.ageFileFilter(reference, true);
        final IOFileFilter filter9 = FileFilterUtils.ageFileFilter(reference, false);

        assertFiltering(filter1, oldFile, true);
        assertFiltering(filter2, oldFile, true);
        assertFiltering(filter3, oldFile, false);
        assertFiltering(filter4, oldFile, true);
        assertFiltering(filter5, oldFile, true);
        assertFiltering(filter6, oldFile, false);
        assertFiltering(filter7, oldFile, true);
        assertFiltering(filter8, oldFile, true);
        assertFiltering(filter9, oldFile, false);
        assertFiltering(filter1, newFile, false);
        assertFiltering(filter2, newFile, false);
        assertFiltering(filter3, newFile, true);
        assertFiltering(filter4, newFile, false);
        assertFiltering(filter5, newFile, false);
        assertFiltering(filter6, newFile, true);
        assertFiltering(filter7, newFile, false);
        assertFiltering(filter8, newFile, false);
        assertFiltering(filter9, newFile, true);
        //
        assertFiltering(filter1, oldPath, true);
        assertFiltering(filter2, oldPath, true);
        assertFiltering(filter3, oldPath, false);
        assertFiltering(filter4, oldPath, true);
        assertFiltering(filter5, oldPath, true);
        assertFiltering(filter6, oldPath, false);
        assertFiltering(filter7, oldPath, true);
        assertFiltering(filter8, oldPath, true);
        assertFiltering(filter9, oldPath, false);
        assertFiltering(filter1, newPath, false);
        assertFiltering(filter2, newPath, false);
        assertFiltering(filter3, newPath, true);
        assertFiltering(filter4, newPath, false);
        assertFiltering(filter5, newPath, false);
        assertFiltering(filter6, newPath, true);
        assertFiltering(filter7, newPath, false);
        assertFiltering(filter8, newPath, false);
        assertFiltering(filter9, newPath, true);
    }

    @Test
    public void testAnd() throws IOException {
        final IOFileFilter trueFilter = TrueFileFilter.INSTANCE;
        final IOFileFilter falseFilter = FalseFileFilter.INSTANCE;
        assertFiltering(trueFilter.and(trueFilter), new File("foo.test"), true);
        assertFiltering(trueFilter.and(falseFilter), new File("foo.test"), false);
        assertFiltering(falseFilter.and(trueFilter), new File("foo.test"), false);
        assertFiltering(falseFilter.and(falseFilter), new File("foo.test"), false);
    }

    @Test
    public void testAnd2() throws IOException {
        final IOFileFilter trueFilter = TrueFileFilter.INSTANCE;
        final IOFileFilter falseFilter = FalseFileFilter.INSTANCE;
        assertFiltering(new AndFileFilter(trueFilter, trueFilter), new File("foo.test"), true);
        assertFiltering(new AndFileFilter(trueFilter, falseFilter), new File("foo.test"), false);
        assertFiltering(new AndFileFilter(falseFilter, trueFilter), new File("foo.test"), false);
        assertFiltering(new AndFileFilter(falseFilter, falseFilter), new File("foo.test"), false);

        final List<IOFileFilter> filters = new ArrayList<>();
        assertFiltering(new AndFileFilter(filters), new File("test"), false);
        assertFiltering(new AndFileFilter(), new File("test"), false);

        assertThrows(NullPointerException.class, () -> new AndFileFilter(falseFilter, null));
        assertThrows(NullPointerException.class, () -> new AndFileFilter(null, falseFilter));
        assertThrows(NullPointerException.class, () -> new AndFileFilter((List<IOFileFilter>) null));
    }

    @Test
    public void testAndArray() throws IOException {
        final IOFileFilter trueFilter = TrueFileFilter.INSTANCE;
        final IOFileFilter falseFilter = FalseFileFilter.INSTANCE;
        assertFiltering(new AndFileFilter(trueFilter, trueFilter, trueFilter), new File("foo.test"), true);
        assertFiltering(new AndFileFilter(trueFilter, falseFilter, falseFilter), new File("foo.test"), false);
        assertFiltering(new AndFileFilter(falseFilter, trueFilter, trueFilter), new File("foo.test"), false);
        assertFiltering(new AndFileFilter(falseFilter, falseFilter, falseFilter), new File("foo.test"), false);

        final List<IOFileFilter> filters = new ArrayList<>();
        assertFiltering(new AndFileFilter(filters), new File("test"), false);
        assertFiltering(new AndFileFilter(), new File("test"), false);
    }

    @Test
    public void testCanExecute() throws Exception {
        assumeTrue(SystemUtils.IS_OS_WINDOWS);
        try (TempFile executablePath = TempFile.create(getClass().getSimpleName(), null)) {
            final File executableFile = executablePath.toFile();
            try (BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(executablePath.get()))) {
                TestUtils.generateTestData(output, 32);
            }
            assertTrue(executableFile.setExecutable(true));
            assertFiltering(CanExecuteFileFilter.CAN_EXECUTE, executablePath.get(), true);
            assertFiltering(CanExecuteFileFilter.CAN_EXECUTE, (Path) null, false);
            assertFiltering(CanExecuteFileFilter.CAN_EXECUTE, executableFile, true);
            assertFiltering(CanExecuteFileFilter.CAN_EXECUTE, (File) null, false);
            executableFile.setExecutable(false);
            assertFiltering(CanExecuteFileFilter.CANNOT_EXECUTE, executablePath.get(), false);
            assertFiltering(CanExecuteFileFilter.CANNOT_EXECUTE, (Path) null, true);
            assertFiltering(CanExecuteFileFilter.CANNOT_EXECUTE, executableFile, false);
            assertFiltering(CanExecuteFileFilter.CANNOT_EXECUTE, (File) null, true);
        }
    }

    @Test
    public void testCanRead() throws Exception {
        final File readOnlyFile = new File(temporaryFolder, "read-only-file1.txt");
        final Path readOnlyPath = readOnlyFile.toPath();
        if (!readOnlyFile.getParentFile().exists()) {
            fail("Cannot create file " + readOnlyFile + " as the parent directory does not exist");
        }
        try (BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(readOnlyFile.toPath()))) {
            TestUtils.generateTestData(output, 32);
        }
        assertTrue(readOnlyFile.setReadOnly());
        assertFiltering(CanReadFileFilter.CAN_READ, readOnlyFile, true);
        assertFiltering(CanReadFileFilter.CAN_READ, (File) null, false);
        assertFiltering(CanReadFileFilter.CAN_READ, readOnlyPath, true);
        assertFiltering(CanReadFileFilter.CAN_READ, (Path) null, false);
        assertFiltering(CanReadFileFilter.CANNOT_READ, readOnlyFile, false);
        assertFiltering(CanReadFileFilter.CANNOT_READ, (File) null, true);
        assertFiltering(CanReadFileFilter.CANNOT_READ, readOnlyPath, false);
        assertFiltering(CanReadFileFilter.CANNOT_READ, (Path) null, true);
        assertFiltering(CanReadFileFilter.READ_ONLY, readOnlyFile, true);
        assertFiltering(CanReadFileFilter.READ_ONLY, (File) null, false);
        assertFiltering(CanReadFileFilter.READ_ONLY, readOnlyPath, true);
        assertFiltering(CanReadFileFilter.READ_ONLY, (Path) null, false);
        readOnlyFile.delete();
    }

    @Test
    public void testCanWrite() throws Exception {
        final File readOnlyFile = new File(temporaryFolder, "read-only-file2.txt");
        final Path readOnlyPath = readOnlyFile.toPath();
        if (!readOnlyFile.getParentFile().exists()) {
            fail("Cannot create file " + readOnlyFile + " as the parent directory does not exist");
        }
        try (BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(readOnlyFile.toPath()))) {
            TestUtils.generateTestData(output, 32);
        }
        assertTrue(readOnlyFile.setReadOnly());
        assertFiltering(CanWriteFileFilter.CAN_WRITE, temporaryFolder, true);
        assertFiltering(CanWriteFileFilter.CAN_WRITE, readOnlyFile, false);
        assertFiltering(CanWriteFileFilter.CAN_WRITE, (File) null, false);
        assertFiltering(CanWriteFileFilter.CAN_WRITE, readOnlyPath, false);
        assertFiltering(CanWriteFileFilter.CAN_WRITE, (Path) null, false);
        assertFiltering(CanWriteFileFilter.CANNOT_WRITE, temporaryFolder, false);
        assertFiltering(CanWriteFileFilter.CANNOT_WRITE, readOnlyFile, true);
        assertFiltering(CanWriteFileFilter.CANNOT_WRITE, readOnlyPath, true);
        assertFiltering(CanWriteFileFilter.CANNOT_WRITE, (File) null, true);
        assertFiltering(CanWriteFileFilter.CANNOT_WRITE, (Path) null, true);
        readOnlyFile.delete();
    }

    @Test
    public void testDelegateFileFilter() throws IOException {
        final OrFileFilter orFilter = new OrFileFilter();
        final File testFile = new File("test.txt");

        IOFileFilter filter = new DelegateFileFilter((FileFilter) orFilter);
        assertFiltering(filter, testFile, false);
        assertNotNull(filter.toString()); // TODO better test

        filter = new DelegateFileFilter((FilenameFilter) orFilter);
        assertFiltering(filter, testFile, false);
        assertNotNull(filter.toString()); // TODO better test

        assertThrows(NullPointerException.class, () -> new DelegateFileFilter((FileFilter) null));
        assertThrows(NullPointerException.class, () -> new DelegateFileFilter((FilenameFilter) null));
    }

    @Test
    public void testDelegation() { // TODO improve these tests
        assertNotNull(FileFilterUtils.asFileFilter((FileFilter) FalseFileFilter.INSTANCE));
        assertNotNull(FileFilterUtils.asFileFilter((FilenameFilter) FalseFileFilter.INSTANCE).toString());
    }

    @SuppressWarnings("deprecation")
    @Test
    public void testDeprecatedWildcard() throws IOException {
        IOFileFilter filter = new WildcardFilter("*.txt");
        final List<String> patternList = Arrays.asList("*.txt", "*.xml", "*.gif");
        final IOFileFilter listFilter = new WildcardFilter(patternList);
        final File txtFile = new File("test.txt");
        final Path txtPath = txtFile.toPath();
        final File bmpFile = new File("test.bmp");
        final Path bmpPath = bmpFile.toPath();
        final File dirFile = new File("src/java");
        final Path dirPath = dirFile.toPath();

        assertFiltering(filter, new File("log.txt"), true);
//        assertFiltering(filter, new File("log.txt.bak"), false);
        assertFiltering(filter, new File("log.txt").toPath(), true);

        filter = new WildcardFilter("log?.txt");
        assertFiltering(filter, new File("log1.txt"), true);
        assertFiltering(filter, new File("log12.txt"), false);
        //
        assertFiltering(filter, new File("log1.txt").toPath(), true);
        assertFiltering(filter, new File("log12.txt").toPath(), false);

        filter = new WildcardFilter("open??.????04");
        assertFiltering(filter, new File("openAB.102504"), true);
        assertFiltering(filter, new File("openA.102504"), false);
        assertFiltering(filter, new File("openXY.123103"), false);
//        assertFiltering(filter, new File("openAB.102504.old"), false);
        //
        assertFiltering(filter, new File("openAB.102504").toPath(), true);
        assertFiltering(filter, new File("openA.102504").toPath(), false);
        assertFiltering(filter, new File("openXY.123103").toPath(), false);
//        assertFiltering(filter, new File("openAB.102504.old").toPath(), false);

        filter = new WildcardFilter("*.java", "*.class");
        assertFiltering(filter, new File("Test.java"), true);
        assertFiltering(filter, new File("Test.class"), true);
        assertFiltering(filter, new File("Test.jsp"), false);
        //
        assertFiltering(filter, new File("Test.java").toPath(), true);
        assertFiltering(filter, new File("Test.class").toPath(), true);
        assertFiltering(filter, new File("Test.jsp").toPath(), false);

        assertFiltering(listFilter, new File("Test.txt"), true);
        assertFiltering(listFilter, new File("Test.xml"), true);
        assertFiltering(listFilter, new File("Test.gif"), true);
        assertFiltering(listFilter, new File("Test.bmp"), false);
        //
        assertFiltering(listFilter, new File("Test.txt").toPath(), true);
        assertFiltering(listFilter, new File("Test.xml").toPath(), true);
        assertFiltering(listFilter, new File("Test.gif").toPath(), true);
        assertFiltering(listFilter, new File("Test.bmp").toPath(), false);

        // File
        assertTrue(listFilter.accept(txtFile));
        assertFalse(listFilter.accept(bmpFile));
        assertFalse(listFilter.accept(dirFile));
        // Path
        assertTrue(listFilter.matches(txtPath));
        assertFalse(listFilter.matches(bmpPath));
        assertFalse(listFilter.matches(dirPath));
        //
        assertEquals(FileVisitResult.CONTINUE, listFilter.accept(txtPath, null));
        assertEquals(FileVisitResult.TERMINATE, listFilter.accept(bmpPath, null));
        assertEquals(FileVisitResult.TERMINATE, listFilter.accept(dirPath, null));

        assertTrue(listFilter.accept(txtFile.getParentFile(), txtFile.getName()));
        assertFalse(listFilter.accept(bmpFile.getParentFile(), bmpFile.getName()));
        assertFalse(listFilter.accept(dirFile.getParentFile(), dirFile.getName()));
        //
        assertEquals(FileVisitResult.CONTINUE, listFilter.accept(txtPath, null));
        assertEquals(FileVisitResult.TERMINATE, listFilter.accept(bmpPath, null));
        assertEquals(FileVisitResult.TERMINATE, listFilter.accept(dirPath, null));

        assertThrows(NullPointerException.class, () -> new WildcardFilter((String) null));
        assertThrows(NullPointerException.class, () -> new WildcardFilter((String[]) null));
        assertThrows(NullPointerException.class, () -> new WildcardFilter((List<String>) null));
    }

    @Test
    public void testDirectory() throws IOException {
        // XXX: This test presumes the current working dir is the base dir of the source checkout.
        final IOFileFilter filter = new DirectoryFileFilter();

        assertFiltering(filter, new File("src/"), true);
        assertFiltering(filter, new File("src/").toPath(), true);
        assertFiltering(filter, new File("src/main/java/"), true);
        assertFiltering(filter, new File("src/main/java/").toPath(), true);

        assertFiltering(filter, new File("pom.xml"), false);
        assertFiltering(filter, new File("pom.xml").toPath(), false);

        assertFiltering(filter, new File("imaginary"), false);
        assertFiltering(filter, new File("imaginary").toPath(), false);
        assertFiltering(filter, new File("imaginary/"), false);
        assertFiltering(filter, new File("imaginary/").toPath(), false);

        assertFiltering(filter, new File("LICENSE.txt"), false);
        assertFiltering(filter, new File("LICENSE.txt").toPath(), false);

        assertFiltering(filter, (File) null, false);
        assertFiltering(filter, (Path) null, false);

        assertSame(DirectoryFileFilter.DIRECTORY, DirectoryFileFilter.INSTANCE);
    }

    @Test
    public void testEmpty() throws Exception {

        // Empty Dir
        final File emptyDirFile = new File(temporaryFolder, "empty-dir");
        final Path emptyDirPath = emptyDirFile.toPath();
        emptyDirFile.mkdirs();
        assertFiltering(EmptyFileFilter.EMPTY, emptyDirFile, true);
        assertFiltering(EmptyFileFilter.EMPTY, emptyDirPath, true);
        assertFiltering(EmptyFileFilter.EMPTY, (File) null, true);
        assertFiltering(EmptyFileFilter.EMPTY, (Path) null, true);
        assertFiltering(EmptyFileFilter.NOT_EMPTY, emptyDirFile, false);
        assertFiltering(EmptyFileFilter.NOT_EMPTY, emptyDirPath, false);
        assertFiltering(EmptyFileFilter.NOT_EMPTY, (File) null, false);
        assertFiltering(EmptyFileFilter.NOT_EMPTY, (Path) null, false);

        // Empty File
        final File emptyFile = new File(emptyDirFile, "empty-file.txt");
        final Path emptyPath = emptyFile.toPath();
        if (!emptyFile.getParentFile().exists()) {
            fail("Cannot create file " + emptyFile + " as the parent directory does not exist");
        }
        try (BufferedOutputStream output1 = new BufferedOutputStream(Files.newOutputStream(emptyFile.toPath()))) {
            TestUtils.generateTestData(output1, 0);
        }
        assertFiltering(EmptyFileFilter.EMPTY, emptyFile, true);
        assertFiltering(EmptyFileFilter.EMPTY, emptyPath, true);
        assertFiltering(EmptyFileFilter.NOT_EMPTY, emptyFile, false);
        assertFiltering(EmptyFileFilter.NOT_EMPTY, emptyPath, false);

        // Not Empty Dir
        assertFiltering(EmptyFileFilter.EMPTY, emptyDirFile, false);
        assertFiltering(EmptyFileFilter.EMPTY, emptyDirPath, false);
        assertFiltering(EmptyFileFilter.NOT_EMPTY, emptyDirFile, true);
        assertFiltering(EmptyFileFilter.NOT_EMPTY, emptyDirPath, true);

        // Not Empty File
        final File notEmptyFile = new File(emptyDirFile, "not-empty-file.txt");
        final Path notEmptyPath = notEmptyFile.toPath();
        if (!notEmptyFile.getParentFile().exists()) {
            fail("Cannot create file " + notEmptyFile + " as the parent directory does not exist");
        }
        try (BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(notEmptyFile.toPath()))) {
            TestUtils.generateTestData(output, 32);
        }
        assertFiltering(EmptyFileFilter.EMPTY, notEmptyFile, false);
        assertFiltering(EmptyFileFilter.EMPTY, notEmptyPath, false);
        assertFiltering(EmptyFileFilter.NOT_EMPTY, notEmptyFile, true);
        assertFiltering(EmptyFileFilter.NOT_EMPTY, notEmptyPath, true);
        FileUtils.forceDelete(emptyDirFile);
    }

    @Test
    public void testEnsureTestCoverage() {
        assertNotNull(new FileFilterUtils()); // dummy for test coverage
    }

    @Test
    public void testFalse() throws IOException {
        final IOFileFilter filter = FileFilterUtils.falseFileFilter();
        assertFiltering(filter, new File("foo.test"), false);
        assertFiltering(filter, new File("foo.test").toPath(), false);
        assertFiltering(filter, new File("foo"), false);
        assertFiltering(filter, new File("foo").toPath(), false);
        assertFiltering(filter, (File) null, false);
        assertFiltering(filter, (Path) null, false);
        assertSame(FalseFileFilter.FALSE, FalseFileFilter.INSTANCE);
        assertSame(TrueFileFilter.TRUE, FalseFileFilter.INSTANCE.negate());
        assertSame(TrueFileFilter.INSTANCE, FalseFileFilter.INSTANCE.negate());
        assertNotNull(FalseFileFilter.INSTANCE.toString());
    }

    @Test
    public void testFileEqualsFilter() throws IOException {
        assertFooBarFileFiltering(
            new FileEqualsFileFilter(new File("foo")).or(new FileEqualsFileFilter(new File("bar"))));
    }

    @Test
    public void testFileFilterUtils_and() throws IOException {
        final IOFileFilter trueFilter = TrueFileFilter.INSTANCE;
        final IOFileFilter falseFilter = FalseFileFilter.INSTANCE;
        assertFiltering(FileFilterUtils.and(trueFilter, trueFilter, trueFilter), new File("foo.test"), true);
        assertFiltering(FileFilterUtils.and(trueFilter, falseFilter, trueFilter), new File("foo.test"), false);
        assertFiltering(FileFilterUtils.and(falseFilter, trueFilter), new File("foo.test"), false);
        assertFiltering(FileFilterUtils.and(falseFilter, falseFilter), new File("foo.test"), false);
    }

    @Test
    public void testFileFilterUtils_or() throws IOException {
        final IOFileFilter trueFilter = TrueFileFilter.INSTANCE;
        final IOFileFilter falseFilter = FalseFileFilter.INSTANCE;
        final File testFile = new File("foo.test");
        assertFiltering(FileFilterUtils.or(trueFilter, trueFilter), testFile, true);
        assertFiltering(FileFilterUtils.or(trueFilter, trueFilter, falseFilter), testFile, true);
        assertFiltering(FileFilterUtils.or(falseFilter, trueFilter), testFile, true);
        assertFiltering(FileFilterUtils.or(falseFilter, falseFilter, falseFilter), testFile, false);
    }

    @Test
    public void testFiles() throws IOException {
        // XXX: This test presumes the current working dir is the base dir of the source checkout.
        final IOFileFilter filter = FileFileFilter.INSTANCE;

        assertFiltering(filter, (File) null, false);
        assertFiltering(filter, new File("src/"), false);
        assertFiltering(filter, new File("src/").toPath(), false);
        assertFiltering(filter, new File("src/java/"), false);
        assertFiltering(filter, new File("src/java/").toPath(), false);

        assertFiltering(filter, new File("pom.xml"), true);
        assertFiltering(filter, new File("pom.xml").toPath(), true);

        assertFiltering(filter, new File("imaginary"), false);
        assertFiltering(filter, new File("imaginary").toPath(), false);
        assertFiltering(filter, new File("imaginary/"), false);
        assertFiltering(filter, new File("imaginary/").toPath(), false);

        assertFiltering(filter, new File("LICENSE.txt"), true);
        assertFiltering(filter, new File("LICENSE.txt").toPath(), true);
    }

    /*
     * Test method for {@link FileFilterUtils#filter(IOFileFilter, java.lang.Iterable)} that tests that the method
     * properly filters files from the list.
     */
    @Test
    public void testFilterArray_fromList() throws Exception {
        final File fileA = TestUtils.newFile(temporaryFolder, "A");
        final File fileB = TestUtils.newFile(temporaryFolder, "B");
        final List<File> fileList = Arrays.asList(fileA, fileB);

        final IOFileFilter filter = FileFilterUtils.nameFileFilter("A");

        final File[] filtered = FileFilterUtils.filter(filter, fileList);

        assertEquals(1, filtered.length);
        assertEquals(fileA, filtered[0]);
    }

    /*
     * Test method for {@link FileFilterUtils#filter(IOFileFilter, File...)} that tests that the method properly filters
     * files from the list.
     */
    @Test
    public void testFilterArray_IOFileFilter() throws Exception {
        final File fileA = TestUtils.newFile(temporaryFolder, "A");
        final File fileB = TestUtils.newFile(temporaryFolder, "B");

        final IOFileFilter filter = FileFilterUtils.nameFileFilter("A");

        final File[] filtered = FileFilterUtils.filter(filter, fileA, fileB);

        assertEquals(1, filtered.length);
        assertEquals(fileA, filtered[0]);
    }

    /*
     * Test method for {@link FileFilterUtils#filter(IOFileFilter, File...)} that tests that the method properly filters
     * files from the list.
     */
    @Test
    public void testFilterArray_PathVisitorFileFilter_FileExistsNo() throws Exception {
        final File fileA = TestUtils.newFile(temporaryFolder, "A");
        final File fileB = TestUtils.newFile(temporaryFolder, "B");

        final IOFileFilter filter = new PathVisitorFileFilter(new NameFileFilter("A"));

        final File[] filtered = FileFilterUtils.filter(filter, fileA, fileB);

        assertEquals(1, filtered.length);
        assertEquals(fileA, filtered[0]);
    }

    /*
     * Test method for {@link FileFilterUtils#filter(IOFileFilter, File...)} that tests that the method properly filters
     * files from the list.
     */
    @Test
    public void testFilterArray_PathVisitorFileFilter_FileExistsYes() throws Exception {
        final File fileA = TestUtils.newFile(temporaryFolder, "A");
        final File fileB = TestUtils.newFile(temporaryFolder, "B");
        FileUtils.write(fileA, "test", StandardCharsets.US_ASCII);

        final IOFileFilter filter = new PathVisitorFileFilter(new NameFileFilter("A"));

        final File[] filtered = FileFilterUtils.filter(filter, fileA, fileB);

        assertEquals(1, filtered.length);
        assertEquals(fileA, filtered[0]);
    }

    /*
     * Test method for {@link FileFilterUtils#filter(IOFileFilter, File...)} that tests {@code null} parameters.
     */
    @Test
    public void testFilterFilesArrayNullParameters() throws Exception {
        final File fileA = TestUtils.newFile(temporaryFolder, "A");
        final File fileB = TestUtils.newFile(temporaryFolder, "B");
        assertThrows(NullPointerException.class, () -> FileFilterUtils.filter(null, fileA, fileB));

        final IOFileFilter filter = FileFilterUtils.trueFileFilter();
        FileFilterUtils.filter(filter, fileA, null);

        final File[] filtered = FileFilterUtils.filter(filter, (File[]) null);
        assertEquals(0, filtered.length);
    }

    /*
     * Test method for {@link FileFilterUtils#filterList(IOFileFilter, java.lang.Iterable)} that tests that the method
     * properly filters files from the list.
     */
    @Test
    public void testFilterList() throws Exception {
        final File fileA = TestUtils.newFile(temporaryFolder, "A");
        final File fileB = TestUtils.newFile(temporaryFolder, "B");
        final List<File> fileList = Arrays.asList(fileA, fileB);

        final IOFileFilter filter = FileFilterUtils.nameFileFilter("A");

        final List<File> filteredList = FileFilterUtils.filterList(filter, fileList);

        assertTrue(filteredList.contains(fileA));
        assertFalse(filteredList.contains(fileB));
    }

    /*
     * Test method for {@link FileFilterUtils#filterList(IOFileFilter, File...)} that tests that the method properly
     * filters files from the list.
     */
    @Test
    public void testFilterList_fromArray() throws Exception {
        final File fileA = TestUtils.newFile(temporaryFolder, "A");
        final File fileB = TestUtils.newFile(temporaryFolder, "B");

        final IOFileFilter filter = FileFilterUtils.nameFileFilter("A");

        final List<File> filteredList = FileFilterUtils.filterList(filter, fileA, fileB);

        assertTrue(filteredList.contains(fileA));
        assertFalse(filteredList.contains(fileB));
    }

    /*
     * Test method for {@link FileFilterUtils#filterList(IOFileFilter, java.lang.Iterable)} that tests {@code null}
     * parameters and {@code null} elements in the provided list.
     */
    @Test
    public void testFilterListNullParameters() {
        assertThrows(NullPointerException.class, () -> FileFilterUtils.filterList(null, Collections.emptyList()));

        final IOFileFilter filter = FileFilterUtils.trueFileFilter();
        List<File> filteredList = FileFilterUtils.filterList(filter, Collections.singletonList(null));
        assertEquals(1, filteredList.size());
        assertNull(filteredList.get(0));

        filteredList = FileFilterUtils.filterList(filter, (List<File>) null);
        assertEquals(0, filteredList.size());
    }

    /*
     * Test method for {@link FileFilterUtils#filter(IOFileFilter, Path...)}.
     */
    @Test
    public void testFilterPathsArrayNullParameters() throws Exception {
        final Path fileA = TestUtils.newFile(temporaryFolder, "A").toPath();
        final Path fileB = TestUtils.newFile(temporaryFolder, "B").toPath();
        assertThrows(NullPointerException.class, () -> PathUtils.filter(null, fileA, fileB));

        final IOFileFilter filter = FileFilterUtils.trueFileFilter();
        PathUtils.filter(filter, fileA, null);

        final File[] filtered = FileFilterUtils.filter(filter, (File[]) null);
        assertEquals(0, filtered.length);
    }

    /*
     * Test method for {@link FileFilterUtils#filterSet(IOFileFilter, java.lang.Iterable)} that tests that the method
     * properly filters files from the set.
     */
    @Test
    public void testFilterSet() throws Exception {
        final File fileA = TestUtils.newFile(temporaryFolder, "A");
        final File fileB = TestUtils.newFile(temporaryFolder, "B");
        final Set<File> fileList = new HashSet<>(Arrays.asList(fileA, fileB));

        final IOFileFilter filter = FileFilterUtils.nameFileFilter("A");

        final Set<File> filteredSet = FileFilterUtils.filterSet(filter, fileList);

        assertTrue(filteredSet.contains(fileA));
        assertFalse(filteredSet.contains(fileB));
    }

    /*
     * Test method for {@link FileFilterUtils#filterSet(IOFileFilter, File...)} that tests that the method properly
     * filters files from the set.
     */
    @Test
    public void testFilterSet_fromArray() throws Exception {
        final File fileA = TestUtils.newFile(temporaryFolder, "A");
        final File fileB = TestUtils.newFile(temporaryFolder, "B");

        final IOFileFilter filter = FileFilterUtils.nameFileFilter("A");

        final Set<File> filteredSet = FileFilterUtils.filterSet(filter, fileA, fileB);

        assertTrue(filteredSet.contains(fileA));
        assertFalse(filteredSet.contains(fileB));
    }

    /*
     * Test method for {@link FileFilterUtils#filterSet(IOFileFilter, java.lang.Iterable)} that tests {@code null}
     * parameters and {@code null} elements in the provided set.
     */
    @Test
    public void testFilterSetNullParameters() {
        assertThrows(NullPointerException.class, () -> FileFilterUtils.filterSet(null, Collections.emptySet()));

        final IOFileFilter filter = FileFilterUtils.trueFileFilter();
        FileFilterUtils.filterSet(filter, new HashSet<>(Collections.singletonList(null)));

        final Set<File> filteredSet = FileFilterUtils.filterSet(filter, (Set<File>) null);
        assertEquals(0, filteredSet.size());
    }

    @Test
    public void testHidden() throws IOException {
        final File hiddenDirFile = new File(SVN_DIR_NAME);
        final Path hiddenDirPath = hiddenDirFile.toPath();
        if (hiddenDirFile.exists()) {
            assertFiltering(HiddenFileFilter.HIDDEN, hiddenDirFile, hiddenDirFile.isHidden());
            assertFiltering(HiddenFileFilter.HIDDEN, hiddenDirPath, hiddenDirFile.isHidden());
            assertFiltering(HiddenFileFilter.VISIBLE, hiddenDirFile, !hiddenDirFile.isHidden());
            assertFiltering(HiddenFileFilter.VISIBLE, hiddenDirPath, !hiddenDirFile.isHidden());
        }
        final Path path = temporaryFolder.toPath();
        assertFiltering(HiddenFileFilter.HIDDEN, temporaryFolder, false);
        assertFiltering(HiddenFileFilter.HIDDEN, path, false);
        assertFiltering(HiddenFileFilter.HIDDEN, (Path) null, true);
        assertFiltering(HiddenFileFilter.VISIBLE, temporaryFolder, true);
        assertFiltering(HiddenFileFilter.VISIBLE, path, true);
        assertFiltering(HiddenFileFilter.VISIBLE, (Path) null, false);
    }

    @Test
    public void testMagicNumberFileFilterBytes() throws Exception {
        final byte[] classFileMagicNumber = {(byte) 0xCA, (byte) 0xFE, (byte) 0xBA, (byte) 0xBE};
        final String xmlFileContent = "<?xml version=\"1.0\" encoding=\"UTF-8\">\n" + "<element>text</element>";

        final File classAFile = new File(temporaryFolder, "A.class");
        final Path classAPath = classAFile.toPath();
        final File xmlBFile = new File(temporaryFolder, "B.xml");
        final Path xmlBPath = xmlBFile.toPath();
        final File emptyFile = new File(temporaryFolder, "C.xml");
        final Path emptyPath = emptyFile.toPath();
        final File dirFile = new File(temporaryFolder, "D");
        final Path dirPath = dirFile.toPath();
        dirFile.mkdirs();

        try (OutputStream classFileAStream = FileUtils.openOutputStream(classAFile)) {
            IOUtils.write(classFileMagicNumber, classFileAStream);
            TestUtils.generateTestData(classFileAStream, 32);
        }

        FileUtils.write(xmlBFile, xmlFileContent, StandardCharsets.UTF_8);
        FileUtils.touch(emptyFile);

        IOFileFilter filter = new MagicNumberFileFilter(classFileMagicNumber);

        assertFiltering(filter, classAFile, true);
        assertFiltering(filter, classAPath, true);
        assertFiltering(filter, xmlBFile, false);
        assertFiltering(filter, xmlBPath, false);
        assertFiltering(filter, emptyFile, false);
        assertFiltering(filter, emptyPath, false);
        assertFiltering(filter, dirFile, false);
        assertFiltering(filter, dirPath, false);

        filter = FileFilterUtils.magicNumberFileFilter(classFileMagicNumber);

        assertFiltering(filter, classAFile, true);
        assertFiltering(filter, classAPath, true);
        assertFiltering(filter, xmlBFile, false);
        assertFiltering(filter, xmlBPath, false);
        assertFiltering(filter, emptyFile, false);
        assertFiltering(filter, emptyPath, false);
        assertFiltering(filter, dirFile, false);
        assertFiltering(filter, dirPath, false);
    }

    @Test
    public void testMagicNumberFileFilterBytesOffset() throws Exception {
        final byte[] tarMagicNumber = {0x75, 0x73, 0x74, 0x61, 0x72};
        final long tarMagicNumberOffset = 257;

        final File tarFileA = new File(temporaryFolder, "A.tar");
        final File randomFileB = new File(temporaryFolder, "B.txt");
        final File dir = new File(temporaryFolder, "D");
        dir.mkdirs();

        try (OutputStream tarFileAStream = FileUtils.openOutputStream(tarFileA)) {
            TestUtils.generateTestData(tarFileAStream, tarMagicNumberOffset);
            IOUtils.write(tarMagicNumber, tarFileAStream);
        }

        if (!randomFileB.getParentFile().exists()) {
            fail("Cannot create file " + randomFileB + " as the parent directory does not exist");
        }
        try (BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(randomFileB.toPath()))) {
            TestUtils.generateTestData(output, 2 * tarMagicNumberOffset);
        }

        IOFileFilter filter = new MagicNumberFileFilter(tarMagicNumber, tarMagicNumberOffset);

        assertFiltering(filter, tarFileA, true);
        assertFiltering(filter, randomFileB, false);
        assertFiltering(filter, dir, false);

        filter = FileFilterUtils.magicNumberFileFilter(tarMagicNumber, tarMagicNumberOffset);

        assertFiltering(filter, tarFileA, true);
        assertFiltering(filter, randomFileB, false);
        assertFiltering(filter, dir, false);
    }

    @Test
    public void testMagicNumberFileFilterString() throws Exception {
        final byte[] classFileMagicNumber = {(byte) 0xCA, (byte) 0xFE, (byte) 0xBA, (byte) 0xBE};
        final String xmlFileContent = "<?xml version=\"1.0\" encoding=\"UTF-8\">\n" + "<element>text</element>";
        final String xmlMagicNumber = "<?xml version=\"1.0\"";

        final File classFileA = new File(temporaryFolder, "A.class");
        final File xmlFileB = new File(temporaryFolder, "B.xml");
        final File dir = new File(temporaryFolder, "D");
        dir.mkdirs();

        try (OutputStream classFileAStream = FileUtils.openOutputStream(classFileA)) {
            IOUtils.write(classFileMagicNumber, classFileAStream);
            TestUtils.generateTestData(classFileAStream, 32);
        }

        FileUtils.write(xmlFileB, xmlFileContent, StandardCharsets.UTF_8);

        IOFileFilter filter = new MagicNumberFileFilter(xmlMagicNumber);

        assertFiltering(filter, classFileA, false);
        assertFiltering(filter, xmlFileB, true);
        assertFiltering(filter, dir, false);

        filter = FileFilterUtils.magicNumberFileFilter(xmlMagicNumber);

        assertFiltering(filter, classFileA, false);
        assertFiltering(filter, xmlFileB, true);
        assertFiltering(filter, dir, false);
    }

    @Test
    public void testMagicNumberFileFilterStringOffset() throws Exception {
        final String tarMagicNumber = "ustar";
        final long tarMagicNumberOffset = 257;

        final File tarFileA = new File(temporaryFolder, "A.tar");
        final File randomFileB = new File(temporaryFolder, "B.txt");
        final File dir = new File(temporaryFolder, "D");
        dir.mkdirs();

        try (OutputStream tarFileAStream = FileUtils.openOutputStream(tarFileA)) {
            TestUtils.generateTestData(tarFileAStream, tarMagicNumberOffset);
            IOUtils.write(tarMagicNumber, tarFileAStream, StandardCharsets.UTF_8);
        }

        if (!randomFileB.getParentFile().exists()) {
            fail("Cannot create file " + randomFileB + " as the parent directory does not exist");
        }
        try (BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(randomFileB.toPath()))) {
            TestUtils.generateTestData(output, 2 * tarMagicNumberOffset);
        }

        IOFileFilter filter = new MagicNumberFileFilter(tarMagicNumber, tarMagicNumberOffset);

        assertFiltering(filter, tarFileA, true);
        assertFiltering(filter, randomFileB, false);
        assertFiltering(filter, dir, false);

        filter = FileFilterUtils.magicNumberFileFilter(tarMagicNumber, tarMagicNumberOffset);

        assertFiltering(filter, tarFileA, true);
        assertFiltering(filter, randomFileB, false);
        assertFiltering(filter, dir, false);
    }

    @Test
    public void testMagicNumberFileFilterValidation() {
        assertThrows(NullPointerException.class, () -> new MagicNumberFileFilter((String) null, 0));
        assertThrows(IllegalArgumentException.class, () -> new MagicNumberFileFilter("0", -1));
        assertThrows(IllegalArgumentException.class, () -> new MagicNumberFileFilter("", 0));
        assertThrows(NullPointerException.class, () -> new MagicNumberFileFilter((byte[]) null, 0));
        assertThrows(IllegalArgumentException.class, () -> new MagicNumberFileFilter(new byte[] {0}, -1));
        assertThrows(IllegalArgumentException.class, () -> new MagicNumberFileFilter(new byte[] {}, 0));
    }

    @Test
    public void testMakeCVSAware() throws Exception {
        final IOFileFilter filter1 = FileFilterUtils.makeCVSAware(null);
        final IOFileFilter filter2 = FileFilterUtils.makeCVSAware(FileFilterUtils.nameFileFilter("test-file1.txt"));

        File file = new File(temporaryFolder, "CVS");
        file.mkdirs();
        assertFiltering(filter1, file, false);
        assertFiltering(filter2, file, false);
        FileUtils.deleteDirectory(file);

        file = new File(temporaryFolder, "test-file1.txt");
        if (!file.getParentFile().exists()) {
            fail("Cannot create file " + file + " as the parent directory does not exist");
        }
        try (BufferedOutputStream output2 = new BufferedOutputStream(Files.newOutputStream(file.toPath()))) {
            TestUtils.generateTestData(output2, 0);
        }
        assertFiltering(filter1, file, true);
        assertFiltering(filter2, file, true);

        file = new File(temporaryFolder, "test-file2.log");
        if (!file.getParentFile().exists()) {
            fail("Cannot create file " + file + " as the parent directory does not exist");
        }
        try (BufferedOutputStream output1 = new BufferedOutputStream(Files.newOutputStream(file.toPath()))) {
            TestUtils.generateTestData(output1, 0);
        }
        assertFiltering(filter1, file, true);
        assertFiltering(filter2, file, false);

        file = new File(temporaryFolder, "CVS");
        if (!file.getParentFile().exists()) {
            fail("Cannot create file " + file + " as the parent directory does not exist");
        }
        try (BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(file.toPath()))) {
            TestUtils.generateTestData(output, 0);
        }
        assertFiltering(filter1, file, true);
        assertFiltering(filter2, file, false);
    }

    @Test
    public void testMakeDirectoryOnly() throws Exception {
        assertSame(DirectoryFileFilter.DIRECTORY, FileFilterUtils.makeDirectoryOnly(null));

        final IOFileFilter filter = FileFilterUtils.makeDirectoryOnly(FileFilterUtils.nameFileFilter("B"));

        final File fileA = new File(temporaryFolder, "A");
        final File fileB = new File(temporaryFolder, "B");

        fileA.mkdirs();
        fileB.mkdirs();

        assertFiltering(filter, fileA, false);
        assertFiltering(filter, fileB, true);

        FileUtils.deleteDirectory(fileA);
        FileUtils.deleteDirectory(fileB);

        if (!fileA.getParentFile().exists()) {
            fail("Cannot create file " + fileA + " as the parent directory does not exist");
        }
        try (BufferedOutputStream output1 = new BufferedOutputStream(Files.newOutputStream(fileA.toPath()))) {
            TestUtils.generateTestData(output1, 32);
        }
        if (!fileB.getParentFile().exists()) {
            fail("Cannot create file " + fileB + " as the parent directory does not exist");
        }
        try (BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(fileB.toPath()))) {
            TestUtils.generateTestData(output, 32);
        }

        assertFiltering(filter, fileA, false);
        assertFiltering(filter, fileB, false);

        fileA.delete();
        fileB.delete();
    }

    @Test
    public void testMakeFileOnly() throws Exception {
        assertSame(FileFileFilter.INSTANCE, FileFilterUtils.makeFileOnly(null));

        final IOFileFilter filter = FileFilterUtils.makeFileOnly(FileFilterUtils.nameFileFilter("B"));

        final File fileA = new File(temporaryFolder, "A");
        final File fileB = new File(temporaryFolder, "B");

        fileA.mkdirs();
        fileB.mkdirs();

        assertFiltering(filter, fileA, false);
        assertFiltering(filter, fileB, false);

        FileUtils.deleteDirectory(fileA);
        FileUtils.deleteDirectory(fileB);

        if (!fileA.getParentFile().exists()) {
            fail("Cannot create file " + fileA + " as the parent directory does not exist");
        }
        try (BufferedOutputStream output1 = new BufferedOutputStream(Files.newOutputStream(fileA.toPath()))) {
            TestUtils.generateTestData(output1, 32);
        }
        if (!fileB.getParentFile().exists()) {
            fail("Cannot create file " + fileB + " as the parent directory does not exist");
        }
        try (BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(fileB.toPath()))) {
            TestUtils.generateTestData(output, 32);
        }

        assertFiltering(filter, fileA, false);
        assertFiltering(filter, fileB, true);

        fileA.delete();
        fileB.delete();
    }

    @Test
    public void testMakeSVNAware() throws Exception {
        final IOFileFilter filter1 = FileFilterUtils.makeSVNAware(null);
        final IOFileFilter filter2 = FileFilterUtils.makeSVNAware(FileFilterUtils.nameFileFilter("test-file1.txt"));

        File file = new File(temporaryFolder, SVN_DIR_NAME);
        file.mkdirs();
        assertFiltering(filter1, file, false);
        assertFiltering(filter2, file, false);
        FileUtils.deleteDirectory(file);

        file = new File(temporaryFolder, "test-file1.txt");
        if (!file.getParentFile().exists()) {
            fail("Cannot create file " + file + " as the parent directory does not exist");
        }
        try (BufferedOutputStream output2 = new BufferedOutputStream(Files.newOutputStream(file.toPath()))) {
            TestUtils.generateTestData(output2, 0);
        }
        assertFiltering(filter1, file, true);
        assertFiltering(filter2, file, true);

        file = new File(temporaryFolder, "test-file2.log");
        if (!file.getParentFile().exists()) {
            fail("Cannot create file " + file + " as the parent directory does not exist");
        }
        try (BufferedOutputStream output1 = new BufferedOutputStream(Files.newOutputStream(file.toPath()))) {
            TestUtils.generateTestData(output1, 0);
        }
        assertFiltering(filter1, file, true);
        assertFiltering(filter2, file, false);

        file = new File(temporaryFolder, SVN_DIR_NAME);
        if (!file.getParentFile().exists()) {
            fail("Cannot create file " + file + " as the parent directory does not exist");
        }
        try (BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(file.toPath()))) {
            TestUtils.generateTestData(output, 0);
        }
        assertFiltering(filter1, file, true);
        assertFiltering(filter2, file, false);
    }

    @Test
    public void testNameFilter() throws IOException {
        final NameFileFilter filter = new NameFileFilter("foo", "bar");
        assertFooBarFileFiltering(filter);
        assertFiltering(filter, (File) null, false);
        assertFiltering(filter, (Path) null, false);
    }

    @Test
    public void testNameFilterNullArgument() {
        final String test = null;
        final String failMessage = "constructing a NameFileFilter with a null String argument should fail.";
        assertThrows(NullPointerException.class, () -> new NameFileFilter(test), failMessage);
        assertThrows(NullPointerException.class, () -> FileFilterUtils.nameFileFilter(test, IOCase.INSENSITIVE), failMessage);
    }

    @Test
    public void testNameFilterNullArrayArgument() {
        assertThrows(NullPointerException.class, () -> new NameFileFilter((String[]) null));
    }

    @Test
    public void testNameFilterNullListArgument() {
        final List<String> test = null;
        assertThrows(NullPointerException.class, () -> new NameFileFilter(test));
    }

    @Test
    public void testNegate() throws IOException {
        final IOFileFilter filter = FileFilterUtils.notFileFilter(FileFilterUtils.trueFileFilter());
        assertFiltering(filter, new File("foo.test"), false);
        assertFiltering(filter, new File("foo"), false);
        assertFiltering(filter.negate(), new File("foo"), true);
        assertFiltering(filter, (File) null, false);
        assertThrows(NullPointerException.class, () -> new NotFileFilter(null));
    }

    @Test
    public void testNullFilters() {
        assertThrows(NullPointerException.class, () -> FileFilterUtils.toList((IOFileFilter) null));
        assertThrows(NullPointerException.class, () -> FileFilterUtils.toList(new IOFileFilter[] {null}));
    }

    @Test
    public void testOr() throws IOException {
        final IOFileFilter trueFilter = TrueFileFilter.INSTANCE;
        final IOFileFilter falseFilter = FalseFileFilter.INSTANCE;
        final File testFile = new File("foo.test");
        final Path testPath = testFile.toPath();
        assertFiltering(new OrFileFilter(trueFilter, trueFilter), testFile, true);
        assertFiltering(new OrFileFilter(trueFilter, falseFilter), testFile, true);
        assertFiltering(new OrFileFilter(falseFilter, trueFilter), testFile, true);
        assertFiltering(new OrFileFilter(falseFilter, falseFilter), testFile, false);
        assertFiltering(new OrFileFilter(), testFile, false);
        //
        assertFiltering(new OrFileFilter(trueFilter, trueFilter), testPath, true);
        assertFiltering(new OrFileFilter(trueFilter, falseFilter), testPath, true);
        assertFiltering(new OrFileFilter(falseFilter, trueFilter), testPath, true);
        assertFiltering(new OrFileFilter(falseFilter, falseFilter), testPath, false);
        assertFiltering(new OrFileFilter(), testPath, false);
        //
        assertFiltering(falseFilter.or(trueFilter), testPath, true);

        final List<IOFileFilter> filters = new ArrayList<>();
        filters.add(trueFilter);
        filters.add(falseFilter);

        final OrFileFilter orFilter = new OrFileFilter(filters);

        assertFiltering(orFilter, testFile, true);
        assertFiltering(orFilter, testPath, true);
        assertEquals(orFilter.getFileFilters(), filters);
        orFilter.removeFileFilter(trueFilter);
        assertFiltering(orFilter, testFile, false);
        assertFiltering(orFilter, testPath, false);
        orFilter.setFileFilters(filters);
        assertFiltering(orFilter, testFile, true);
        assertFiltering(orFilter, testPath, true);

        assertTrue(orFilter.accept(testFile.getParentFile(), testFile.getName()));
        assertEquals(FileVisitResult.CONTINUE, orFilter.accept(testPath, null));
        assertTrue(orFilter.matches(testPath));
        orFilter.removeFileFilter(trueFilter);
        assertFalse(orFilter.accept(testFile.getParentFile(), testFile.getName()));
        assertEquals(FileVisitResult.TERMINATE, orFilter.accept(testPath, null));
        assertFalse(orFilter.matches(testPath));

        assertThrows(NullPointerException.class, () -> new OrFileFilter(falseFilter, null));
    }

    @Test
    public void testPathEqualsFilter() throws IOException {
        assertFooBarFileFiltering(
            new PathEqualsFileFilter(Paths.get("foo")).or(new PathEqualsFileFilter(Paths.get("bar"))));
    }

    @Test
    public void testPrefix() throws IOException {
        IOFileFilter filter = new PrefixFileFilter("foo", "bar");
        final File testFile = new File("test");
        final Path testPath = testFile.toPath();
        final File fredFile = new File("fred");
        final Path fredPath = fredFile.toPath();

        assertFiltering(filter, new File("foo.test"), true);
        assertFiltering(filter, new File("FOO.test"), false); // case-sensitive
        assertFiltering(filter, new File("foo"), true);
        assertFiltering(filter, new File("bar"), true);
        assertFiltering(filter, new File("food/"), true);
        //
        assertFiltering(filter, new File("foo.test").toPath(), true);
        assertFiltering(filter, new File("FOO.test").toPath(), false); // case-sensitive
        assertFiltering(filter, new File("foo").toPath(), true);
        assertFiltering(filter, new File("bar").toPath(), true);
        assertFiltering(filter, new File("food/").toPath(), true);

        filter = FileFilterUtils.prefixFileFilter("bar");
        assertFiltering(filter, new File("barred\\"), true);
        assertFiltering(filter, new File("test"), false);
        assertFiltering(filter, new File("fo_o.test"), false);
        assertFiltering(filter, new File("abar.exe"), false);
        //
        assertFiltering(filter, new File("barred\\").toPath(), true);
        assertFiltering(filter, new File("test").toPath(), false);
        assertFiltering(filter, new File("fo_o.test").toPath(), false);
        assertFiltering(filter, new File("abar.exe").toPath(), false);

        filter = new PrefixFileFilter("tes");
        assertFiltering(filter, new File("test"), true);
        assertFiltering(filter, new File("fred"), false);
        //
        assertFiltering(filter, new File("test").toPath(), true);
        assertFiltering(filter, new File("fred").toPath(), false);

        assertTrue(filter.accept(testFile.getParentFile(), testFile.getName()));
        assertFalse(filter.accept(fredFile.getParentFile(), fredFile.getName()));
        //
        assertEquals(FileVisitResult.CONTINUE, filter.accept(testPath, null));
        assertEquals(FileVisitResult.TERMINATE, filter.accept(fredPath, null));
        //
        assertTrue(filter.matches(testPath));
        assertFalse(filter.matches(fredPath));

        final List<String> prefixes = Arrays.asList("foo", "fre");
        final IOFileFilter listFilter = new PrefixFileFilter(prefixes);

        assertFalse(listFilter.accept(testFile.getParentFile(), testFile.getName()));
        assertTrue(listFilter.accept(fredFile.getParentFile(), fredFile.getName()));
        //
        assertEquals(FileVisitResult.TERMINATE, listFilter.accept(testPath, null));
        assertEquals(FileVisitResult.CONTINUE, listFilter.accept(fredPath, null));
        //
        assertFalse(listFilter.matches(testPath));
        assertTrue(listFilter.matches(fredPath));

        assertThrows(NullPointerException.class, () -> new PrefixFileFilter((String) null));
        assertThrows(NullPointerException.class, () -> new PrefixFileFilter((String[]) null));
        assertThrows(NullPointerException.class, () -> new PrefixFileFilter((List<String>) null));
    }

    @Test
    public void testPrefixCaseInsensitive() throws IOException {

        IOFileFilter filter = new PrefixFileFilter(new String[] {"foo", "bar"}, IOCase.INSENSITIVE);
        assertFiltering(filter, new File("foo.test1"), true);
        assertFiltering(filter, new File("bar.test1"), true);
        assertFiltering(filter, new File("FOO.test1"), true); // case-insensitive
        assertFiltering(filter, new File("BAR.test1"), true); // case-insensitive

        filter = new PrefixFileFilter("bar", IOCase.INSENSITIVE);
        assertFiltering(filter, new File("foo.test2"), false);
        assertFiltering(filter, new File("bar.test2"), true);
        assertFiltering(filter, new File("FOO.test2"), false); // case-insensitive
        assertFiltering(filter, new File("BAR.test2"), true); // case-insensitive

        final List<String> prefixes = Arrays.asList("foo", "bar");
        filter = new PrefixFileFilter(prefixes, IOCase.INSENSITIVE);
        assertFiltering(filter, new File("foo.test3"), true);
        assertFiltering(filter, new File("bar.test3"), true);
        assertFiltering(filter, new File("FOO.test3"), true); // case-insensitive
        assertFiltering(filter, new File("BAR.test3"), true); // case-insensitive

        assertThrows(NullPointerException.class, () -> new PrefixFileFilter((String) null, IOCase.INSENSITIVE));
        assertThrows(NullPointerException.class, () -> new PrefixFileFilter((String[]) null, IOCase.INSENSITIVE));
        assertThrows(NullPointerException.class, () -> new PrefixFileFilter((List<String>) null, IOCase.INSENSITIVE));
        // FileFilterUtils.prefixFileFilter(String, IOCase) tests
        filter = FileFilterUtils.prefixFileFilter("bar", IOCase.INSENSITIVE);
        assertFiltering(filter, new File("foo.test2"), false);
        assertFiltering(filter, new File("bar.test2"), true);
        assertFiltering(filter, new File("FOO.test2"), false); // case-insensitive
        assertFiltering(filter, new File("BAR.test2"), true); // case-insensitive

        assertThrows(NullPointerException.class, () -> FileFilterUtils.prefixFileFilter(null, IOCase.INSENSITIVE));
    }

    @Test
    public void testSizeFilterOnFiles() throws Exception {
        final File smallFile = new File(temporaryFolder, "small.txt");
        if (!smallFile.getParentFile().exists()) {
            fail("Cannot create file " + smallFile + " as the parent directory does not exist");
        }
        try (BufferedOutputStream output1 = new BufferedOutputStream(Files.newOutputStream(smallFile.toPath()))) {
            TestUtils.generateTestData(output1, 32);
        }
        final File largeFile = new File(temporaryFolder, "large.txt");
        if (!largeFile.getParentFile().exists()) {
            fail("Cannot create file " + largeFile + " as the parent directory does not exist");
        }
        try (BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(largeFile.toPath()))) {
            TestUtils.generateTestData(output, 128);
        }
        final IOFileFilter filter1 = FileFilterUtils.sizeFileFilter(64);
        final IOFileFilter filter2 = FileFilterUtils.sizeFileFilter(64, true);
        final IOFileFilter filter3 = FileFilterUtils.sizeFileFilter(64, false);

        assertFiltering(filter1, smallFile, false);
        assertFiltering(filter2, smallFile, false);
        assertFiltering(filter3, smallFile, true);
        assertFiltering(filter1, largeFile, true);
        assertFiltering(filter2, largeFile, true);
        assertFiltering(filter3, largeFile, false);

        // size range tests
        final IOFileFilter filter4 = FileFilterUtils.sizeRangeFileFilter(33, 127);
        final IOFileFilter filter5 = FileFilterUtils.sizeRangeFileFilter(32, 127);
        final IOFileFilter filter6 = FileFilterUtils.sizeRangeFileFilter(33, 128);
        final IOFileFilter filter7 = FileFilterUtils.sizeRangeFileFilter(31, 129);
        final IOFileFilter filter8 = FileFilterUtils.sizeRangeFileFilter(128, 128);

        assertFiltering(filter4, smallFile, false);
        assertFiltering(filter4, largeFile, false);
        assertFiltering(filter5, smallFile, true);
        assertFiltering(filter5, largeFile, false);
        assertFiltering(filter6, smallFile, false);
        assertFiltering(filter6, largeFile, true);
        assertFiltering(filter7, smallFile, true);
        assertFiltering(filter7, largeFile, true);
        assertFiltering(filter8, largeFile, true);

        assertThrows(IllegalArgumentException.class, () -> FileFilterUtils.sizeFileFilter(-1));
    }

    @Test
    public void testSizeFilterOnPaths() throws Exception {
        final Path smallFile = Paths.get(temporaryFolder.toString(), "small.txt");
        if (Files.notExists(smallFile.getParent())) {
            fail("Cannot create file " + smallFile + " as the parent directory does not exist");
        }
        try (OutputStream output = Files.newOutputStream(smallFile)) {
            TestUtils.generateTestData(output, 32);
        }
        final Path largeFile = Paths.get(temporaryFolder.toString(), "large.txt");
        if (Files.notExists(largeFile.getParent())) {
            fail("Cannot create file " + largeFile + " as the parent directory does not exist");
        }
        try (OutputStream output = Files.newOutputStream(largeFile)) {
            TestUtils.generateTestData(output, 128);
        }
        final IOFileFilter filter1 = FileFilterUtils.sizeFileFilter(64);
        final IOFileFilter filter2 = FileFilterUtils.sizeFileFilter(64, true);
        final IOFileFilter filter3 = FileFilterUtils.sizeFileFilter(64, false);

        assertFiltering(filter1, smallFile, false);
        assertFiltering(filter2, smallFile, false);
        assertFiltering(filter3, smallFile, true);
        assertFiltering(filter1, largeFile, true);
        assertFiltering(filter2, largeFile, true);
        assertFiltering(filter3, largeFile, false);

        // size range tests
        final IOFileFilter filter4 = FileFilterUtils.sizeRangeFileFilter(33, 127);
        final IOFileFilter filter5 = FileFilterUtils.sizeRangeFileFilter(32, 127);
        final IOFileFilter filter6 = FileFilterUtils.sizeRangeFileFilter(33, 128);
        final IOFileFilter filter7 = FileFilterUtils.sizeRangeFileFilter(31, 129);
        final IOFileFilter filter8 = FileFilterUtils.sizeRangeFileFilter(128, 128);

        assertFiltering(filter4, smallFile, false);
        assertFiltering(filter4, largeFile, false);
        assertFiltering(filter5, smallFile, true);
        assertFiltering(filter5, largeFile, false);
        assertFiltering(filter6, smallFile, false);
        assertFiltering(filter6, largeFile, true);
        assertFiltering(filter7, smallFile, true);
        assertFiltering(filter7, largeFile, true);
        assertFiltering(filter8, largeFile, true);

        assertThrows(IllegalArgumentException.class, () -> FileFilterUtils.sizeFileFilter(-1));
    }

    @Test
    public void testSuffix() throws IOException {
        IOFileFilter filter = new SuffixFileFilter("tes", "est");
        final File testFile = new File("test");
        final Path testPath = testFile.toPath();
        final File fredFile = new File("fred");
        final Path fredPath = fredFile.toPath();
        //
        assertFiltering(filter, new File("fred.tes"), true);
        assertFiltering(filter, new File("fred.est"), true);
        assertFiltering(filter, new File("fred.EST"), false); // case-sensitive
        assertFiltering(filter, new File("fred.exe"), false);
        //
        assertFiltering(filter, new File("fred.tes").toPath(), true);
        assertFiltering(filter, new File("fred.est").toPath(), true);
        assertFiltering(filter, new File("fred.EST").toPath(), false); // case-sensitive
        assertFiltering(filter, new File("fred.exe").toPath(), false);

        filter = FileFilterUtils.or(FileFilterUtils.suffixFileFilter("tes"), FileFilterUtils.suffixFileFilter("est"));
        assertFiltering(filter, new File("fred"), false);
        assertFiltering(filter, new File(".tes"), true);
        assertFiltering(filter, new File("fred.test"), true);
        //
        assertFiltering(filter, new File("fred").toPath(), false);
        assertFiltering(filter, new File(".tes").toPath(), true);
        assertFiltering(filter, new File("fred.test").toPath(), true);

        filter = new SuffixFileFilter("est");
        assertFiltering(filter, new File("test"), true);
        assertFiltering(filter, new File("fred"), false);
        //
        assertFiltering(filter, new File("test").toPath(), true);
        assertFiltering(filter, new File("fred").toPath(), false);

        assertTrue(filter.accept(testFile.getParentFile(), testFile.getName()));
        assertFalse(filter.accept(fredFile.getParentFile(), fredFile.getName()));
        //
        assertEquals(FileVisitResult.CONTINUE, filter.accept(testPath, null));
        assertEquals(FileVisitResult.TERMINATE, filter.accept(fredPath, null));
        //
        assertTrue(filter.matches(testPath));
        assertFalse(filter.matches(fredPath));

        final List<String> prefixes = Arrays.asList("ood", "red");
        final IOFileFilter listFilter = new SuffixFileFilter(prefixes);

        assertFalse(listFilter.accept(testFile.getParentFile(), testFile.getName()));
        assertTrue(listFilter.accept(fredFile.getParentFile(), fredFile.getName()));
        //
        assertEquals(FileVisitResult.TERMINATE, listFilter.accept(testPath, null));
        assertEquals(FileVisitResult.CONTINUE, listFilter.accept(fredPath, null));

        assertThrows(NullPointerException.class, () -> new SuffixFileFilter((String) null));
        assertThrows(NullPointerException.class, () -> new SuffixFileFilter((String[]) null));
        assertThrows(NullPointerException.class, () -> new SuffixFileFilter((List<String>) null));
    }

    @Test
    public void testSuffixCaseInsensitive() throws IOException {

        IOFileFilter filter = new SuffixFileFilter(new String[] {"tes", "est"}, IOCase.INSENSITIVE);
        assertFiltering(filter, new File("foo.tes"), true);
        assertFiltering(filter, new File("foo.est"), true);
        assertFiltering(filter, new File("foo.EST"), true); // case-sensitive
        assertFiltering(filter, new File("foo.TES"), true); // case-sensitive
        assertFiltering(filter, new File("foo.exe"), false);

        filter = new SuffixFileFilter("est", IOCase.INSENSITIVE);
        assertFiltering(filter, new File("test"), true);
        assertFiltering(filter, new File("TEST"), true);

        final List<String> suffixes = Arrays.asList("tes", "est");
        filter = new SuffixFileFilter(suffixes, IOCase.INSENSITIVE);
        assertFiltering(filter, new File("bar.tes"), true);
        assertFiltering(filter, new File("bar.est"), true);
        assertFiltering(filter, new File("bar.EST"), true); // case-sensitive
        assertFiltering(filter, new File("bar.TES"), true); // case-sensitive
        assertFiltering(filter, new File("bar.exe"), false);

        assertThrows(NullPointerException.class, () -> new SuffixFileFilter((String) null, IOCase.INSENSITIVE));
        assertThrows(NullPointerException.class, () -> new SuffixFileFilter((String[]) null, IOCase.INSENSITIVE));
        assertThrows(NullPointerException.class, () -> new SuffixFileFilter((List<String>) null, IOCase.INSENSITIVE));

        // FileFilterUtils.suffixFileFilter(String, IOCase) tests
        filter = FileFilterUtils.suffixFileFilter("est", IOCase.INSENSITIVE);
        assertFiltering(filter, new File("test"), true);
        assertFiltering(filter, new File("TEST"), true);

        assertThrows(NullPointerException.class, () -> FileFilterUtils.suffixFileFilter(null, IOCase.INSENSITIVE));
    }

    @Test
    public void testTrue() throws IOException {
        final IOFileFilter filter = FileFilterUtils.trueFileFilter();
        assertFiltering(filter, new File("foo.test"), true);
        assertFiltering(filter, new File("foo"), true);
        assertFiltering(filter, (File) null, true);
        //
        assertFiltering(filter, new File("foo.test").toPath(), true);
        assertFiltering(filter, new File("foo").toPath(), true);
        assertFiltering(filter, (Path) null, true);
        //
        assertSame(TrueFileFilter.TRUE, TrueFileFilter.INSTANCE);
        assertSame(FalseFileFilter.FALSE, TrueFileFilter.INSTANCE.negate());
        assertSame(FalseFileFilter.INSTANCE, TrueFileFilter.INSTANCE.negate());
        assertNotNull(TrueFileFilter.INSTANCE.toString());
    }

}
