diff --git a/src/versionnumber.cpp b/src/versionnumber.cpp
new file mode 100644
--- /dev/null
+++ b/src/versionnumber.cpp
@@ -0,0 +1,103 @@
+/*
+  Copyright © 2017 Hasan Yavuz Özderya
+
+  This file is part of serialplot.
+
+  serialplot 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.
+
+  serialplot 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 serialplot.  If not, see .
+*/
+
+#include 
+
+#include "versionnumber.h"
+
+VersionNumber::VersionNumber(unsigned mj, unsigned mn, unsigned pt)
+{
+    major = mj;
+    minor = mn;
+    patch = pt;
+}
+
+QString VersionNumber::toString() const
+{
+    return QString("%1.%2.%3").arg(major).arg(minor).arg(patch);
+}
+
+bool VersionNumber::extract(const QString& str, VersionNumber& number)
+{
+    QRegularExpression regexp("(?:[-_vV \\t]|^)(?\\d+)"
+                              "(?:\\.(?\\d+))?(?:\\.(?\\d+))?[-_ \\t]?");
+    auto match = regexp.match(str, 0, QRegularExpression::PartialPreferCompleteMatch);
+
+    if (!(match.hasMatch() || match.hasPartialMatch())) return false;
+
+    number.major = match.captured("major").toUInt();
+
+    auto zeroIfNull = [](QString str) -> unsigned
+        {
+            if (str.isNull()) return 0;
+            return str.toUInt();
+        };
+
+    number.minor = zeroIfNull(match.captured("minor"));
+    number.patch = zeroIfNull(match.captured("patch"));
+
+    return true;
+}
+
+bool operator==(const VersionNumber& lhs, const VersionNumber& rhs)
+{
+    return lhs.major == rhs.major &&
+           lhs.minor == rhs.minor &&
+           lhs.patch == rhs.patch;
+}
+
+bool operator<(const VersionNumber& lhs, const VersionNumber& rhs)
+{
+    if (lhs.major < rhs.major)
+    {
+        return true;
+    }
+    else if (lhs.major == rhs.major)
+    {
+        if (lhs.minor < rhs.minor)
+        {
+             return true;
+        }
+        else if (lhs.minor == rhs.minor)
+        {
+            if (lhs.patch < rhs.patch) return true;
+        }
+    }
+    return false;
+}
+
+bool operator>(const VersionNumber& lhs, const VersionNumber& rhs)
+{
+    if (lhs.major > rhs.major)
+    {
+        return true;
+    }
+    else if (lhs.major == rhs.major)
+    {
+        if (lhs.minor > rhs.minor)
+        {
+             return true;
+        }
+        else if (lhs.minor == rhs.minor)
+        {
+            if (lhs.patch > rhs.patch) return true;
+        }
+    }
+    return false;
+}