diff --git a/CMakeLists.txt b/CMakeLists.txt
index 23169e46..3647c944 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -198,6 +198,7 @@ set (LIBLOOT_SRC "${CMAKE_BINARY_DIR}/generated/loot_version.cpp"
"${CMAKE_SOURCE_DIR}/src/api/metadata/condition_evaluator.cpp"
"${CMAKE_SOURCE_DIR}/src/api/metadata/conditional_metadata.cpp"
"${CMAKE_SOURCE_DIR}/src/api/metadata/file.cpp"
+ "${CMAKE_SOURCE_DIR}/src/api/metadata/filename.cpp"
"${CMAKE_SOURCE_DIR}/src/api/metadata/group.cpp"
"${CMAKE_SOURCE_DIR}/src/api/metadata/location.cpp"
"${CMAKE_SOURCE_DIR}/src/api/metadata/message.cpp"
@@ -239,6 +240,7 @@ set (LIBLOOT_HEADERS "${CMAKE_SOURCE_DIR}/include/loot/api.h"
"${CMAKE_SOURCE_DIR}/include/loot/loot_version.h"
"${CMAKE_SOURCE_DIR}/include/loot/metadata/conditional_metadata.h"
"${CMAKE_SOURCE_DIR}/include/loot/metadata/file.h"
+ "${CMAKE_SOURCE_DIR}/include/loot/metadata/filename.h"
"${CMAKE_SOURCE_DIR}/include/loot/metadata/group.h"
"${CMAKE_SOURCE_DIR}/include/loot/metadata/location.h"
"${CMAKE_SOURCE_DIR}/include/loot/metadata/message.h"
diff --git a/include/loot/metadata/filename.h b/include/loot/metadata/filename.h
new file mode 100644
index 00000000..be37fa8d
--- /dev/null
+++ b/include/loot/metadata/filename.h
@@ -0,0 +1,98 @@
+/* LOOT
+
+ A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
+ Fallout: New Vegas.
+
+ Copyright (C) 2012-2016 WrinklyNinja
+
+ This file is part of LOOT.
+
+ LOOT is free software: you can redistribute
+ it and/or modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ LOOT is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LOOT. If not, see
+ .
+ */
+#ifndef LOOT_METADATA_FILENAME
+#define LOOT_METADATA_FILENAME
+
+#include
+
+#include "loot/api_decorator.h"
+
+namespace loot {
+/**
+ * Represents a case-insensitive filename.
+ */
+class Filename {
+public:
+ /**
+ * Construct a Filename using an empty string.
+ * @return A Filename object.
+ */
+ LOOT_API explicit Filename();
+
+ /**
+ * Construct a Filename using the given string.
+ * @return A Filename object.
+ */
+ LOOT_API explicit Filename(const std::string& filename);
+
+ LOOT_API explicit operator std::string() const;
+private:
+ std::string filename_;
+};
+
+/**
+ * Check if two Filename objects are equal by comparing their fields.
+ * @returns True if the filenames are case-insensitively equal and all other
+ * fields are case-sensitively equal, false otherwise.
+ */
+LOOT_API bool operator==(const Filename& lhs,const Filename& rhs);
+
+/**
+ * Check if two Filename objects are not equal.
+ * @returns True if the Filename objects are not equal, false otherwise.
+ */
+LOOT_API bool operator!=(const Filename& lhs, const Filename& rhs);
+
+/**
+ * A less-than operator implemented with no semantics so that Filename objects can
+ * be stored in sets.
+ * @returns True if this Filename is less than the given Filename, false otherwise.
+ */
+LOOT_API bool operator<(const Filename& lhs,const Filename& rhs);
+
+/**
+ * Check if the first Filename object is greater than the second Filename object.
+ * @returns True if the second Filename object is less than the first Filename object,
+ * false otherwise.
+ */
+LOOT_API bool operator>(const Filename& lhs, const Filename& rhs);
+
+/**
+ * Check if the first Filename object is less than or equal to the second Filename
+ * object.
+ * @returns True if the first Filename object is not greater than the second Filename
+ * object, false otherwise.
+ */
+LOOT_API bool operator<=(const Filename& lhs, const Filename& rhs);
+
+/**
+ * Check if the first Filename object is greater than or equal to the second Filename
+ * object.
+ * @returns True if the first Filename object is not less than the second Filename
+ * object, false otherwise.
+ */
+LOOT_API bool operator>=(const Filename& lhs, const Filename& rhs);
+}
+
+#endif
diff --git a/src/api/metadata/filename.cpp b/src/api/metadata/filename.cpp
new file mode 100644
index 00000000..a5e0b2bd
--- /dev/null
+++ b/src/api/metadata/filename.cpp
@@ -0,0 +1,52 @@
+/* LOOT
+
+ A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
+ Fallout: New Vegas.
+
+ Copyright (C) 2012-2016 WrinklyNinja
+
+ This file is part of LOOT.
+
+ LOOT is free software: you can redistribute
+ it and/or modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ LOOT is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LOOT. If not, see
+ .
+ */
+
+#include "loot/metadata/filename.h"
+
+#include "api/helpers/text.h"
+
+namespace loot {
+Filename::Filename() {}
+
+Filename::Filename(const std::string& filename) :
+ filename_(filename) {}
+
+Filename::operator std::string() const { return filename_; }
+
+bool operator==(const Filename& lhs, const Filename& rhs) {
+ return CompareFilenames(std::string(lhs), std::string(rhs)) == 0;
+}
+
+bool operator!=(const Filename& lhs, const Filename& rhs) { return !(lhs == rhs); }
+
+bool operator<(const Filename& lhs, const Filename& rhs) {
+ return CompareFilenames(std::string(lhs), std::string(rhs)) < 0;
+}
+
+bool operator>(const Filename& lhs, const Filename& rhs) { return rhs < lhs; }
+
+bool operator<=(const Filename& lhs, const Filename& rhs) { return !(lhs > rhs); }
+
+bool operator>=(const Filename& lhs, const Filename& rhs) { return !(lhs < rhs); }
+}