diff --git a/src/EntityManager.cpp b/src/EntityManager.cpp
index 725f2bf..8bd97fd 100644
--- a/src/EntityManager.cpp
+++ b/src/EntityManager.cpp
@@ -109,222 +109,6 @@
     return ptr;
 }
 
-// probes dbus interface dictionary for a key with a value that matches a regex
-// When an interface passes a probe, also save its D-Bus path with it.
-bool probeDbus(const std::string& interface,
-               const std::map<std::string, nlohmann::json>& matches,
-               FoundDeviceT& devices, const std::shared_ptr<PerformScan>& scan,
-               bool& foundProbe)
-{
-    bool foundMatch = false;
-    foundProbe = false;
-
-    for (const auto& [path, interfaces] : scan->dbusProbeObjects)
-    {
-        auto it = interfaces.find(interface);
-        if (it == interfaces.end())
-        {
-            continue;
-        }
-
-        foundProbe = true;
-
-        bool deviceMatches = true;
-        const boost::container::flat_map<std::string, BasicVariantType>&
-            properties = it->second;
-
-        for (const auto& [matchProp, matchJSON] : matches)
-        {
-            auto deviceValue = properties.find(matchProp);
-            if (deviceValue != properties.end())
-            {
-                deviceMatches =
-                    deviceMatches && matchProbe(matchJSON, deviceValue->second);
-            }
-            else
-            {
-                // Move on to the next DBus path
-                deviceMatches = false;
-                break;
-            }
-        }
-        if (deviceMatches)
-        {
-            if constexpr (debug)
-            {
-                std::cerr << "probeDBus: Found probe match on " << path << " "
-                          << interface << "\n";
-            }
-            devices.emplace_back(properties, path);
-            foundMatch = true;
-        }
-    }
-    return foundMatch;
-}
-
-// default probe entry point, iterates a list looking for specific types to
-// call specific probe functions
-bool probe(const std::vector<std::string>& probeCommand,
-           const std::shared_ptr<PerformScan>& scan, FoundDeviceT& foundDevs)
-{
-    const static std::regex command(R"(\((.*)\))");
-    std::smatch match;
-    bool ret = false;
-    bool matchOne = false;
-    bool cur = true;
-    probe_type_codes lastCommand = probe_type_codes::FALSE_T;
-    bool first = true;
-
-    for (auto& probe : probeCommand)
-    {
-        bool foundProbe = false;
-        boost::container::flat_map<const char*, probe_type_codes,
-                                   CmpStr>::const_iterator probeType;
-
-        for (probeType = probeTypes.begin(); probeType != probeTypes.end();
-             ++probeType)
-        {
-            if (probe.find(probeType->first) != std::string::npos)
-            {
-                foundProbe = true;
-                break;
-            }
-        }
-        if (foundProbe)
-        {
-            switch (probeType->second)
-            {
-                case probe_type_codes::FALSE_T:
-                {
-                    cur = false;
-                    break;
-                }
-                case probe_type_codes::TRUE_T:
-                {
-                    cur = true;
-                    break;
-                }
-                case probe_type_codes::MATCH_ONE:
-                {
-                    // set current value to last, this probe type shouldn't
-                    // affect the outcome
-                    cur = ret;
-                    matchOne = true;
-                    break;
-                }
-                /*case probe_type_codes::AND:
-                  break;
-                case probe_type_codes::OR:
-                  break;
-                  // these are no-ops until the last command switch
-                  */
-                case probe_type_codes::FOUND:
-                {
-                    if (!std::regex_search(probe, match, command))
-                    {
-                        std::cerr << "found probe syntax error " << probe
-                                  << "\n";
-                        return false;
-                    }
-                    std::string commandStr = *(match.begin() + 1);
-                    boost::replace_all(commandStr, "'", "");
-                    cur = (std::find(scan->passedProbes.begin(),
-                                     scan->passedProbes.end(),
-                                     commandStr) != scan->passedProbes.end());
-                    break;
-                }
-                default:
-                {
-                    break;
-                }
-            }
-        }
-        // look on dbus for object
-        else
-        {
-            if (!std::regex_search(probe, match, command))
-            {
-                std::cerr << "dbus probe syntax error " << probe << "\n";
-                return false;
-            }
-            std::string commandStr = *(match.begin() + 1);
-            // convert single ticks and single slashes into legal json
-            boost::replace_all(commandStr, "'", "\"");
-            boost::replace_all(commandStr, R"(\)", R"(\\)");
-            auto json = nlohmann::json::parse(commandStr, nullptr, false);
-            if (json.is_discarded())
-            {
-                std::cerr << "dbus command syntax error " << commandStr << "\n";
-                return false;
-            }
-            // we can match any (string, variant) property. (string, string)
-            // does a regex
-            std::map<std::string, nlohmann::json> dbusProbeMap =
-                json.get<std::map<std::string, nlohmann::json>>();
-            auto findStart = probe.find('(');
-            if (findStart == std::string::npos)
-            {
-                return false;
-            }
-            std::string probeInterface = probe.substr(0, findStart);
-            cur = probeDbus(probeInterface, dbusProbeMap, foundDevs, scan,
-                            foundProbe);
-        }
-
-        // some functions like AND and OR only take affect after the
-        // fact
-        if (lastCommand == probe_type_codes::AND)
-        {
-            ret = cur && ret;
-        }
-        else if (lastCommand == probe_type_codes::OR)
-        {
-            ret = cur || ret;
-        }
-
-        if (first)
-        {
-            ret = cur;
-            first = false;
-        }
-        lastCommand = probeType != probeTypes.end() ? probeType->second
-                                                    : probe_type_codes::FALSE_T;
-    }
-
-    // probe passed, but empty device
-    if (ret && foundDevs.size() == 0)
-    {
-        foundDevs.emplace_back(
-            boost::container::flat_map<std::string, BasicVariantType>{},
-            std::string{});
-    }
-    if (matchOne && ret)
-    {
-        // match the last one
-        auto last = foundDevs.back();
-        foundDevs.clear();
-
-        foundDevs.emplace_back(std::move(last));
-    }
-    return ret;
-}
-
-PerformProbe::PerformProbe(
-    const std::vector<std::string>& probeCommand,
-    std::shared_ptr<PerformScan>& scanPtr,
-    std::function<void(FoundDeviceT&, const DBusProbeObjectT&)>&& callback) :
-    _probeCommand(probeCommand),
-    scan(scanPtr), _callback(std::move(callback))
-{}
-PerformProbe::~PerformProbe()
-{
-    FoundDeviceT foundDevs;
-    if (probe(_probeCommand, scan, foundDevs))
-    {
-        _callback(foundDevs, scan->dbusProbeObjects);
-    }
-}
-
 // writes output files to persist data
 bool writeJsonFiles(const nlohmann::json& systemConfiguration)
 {
diff --git a/src/PerformProbe.cpp b/src/PerformProbe.cpp
new file mode 100644
index 0000000..7024e47
--- /dev/null
+++ b/src/PerformProbe.cpp
@@ -0,0 +1,248 @@
+/*
+// Copyright (c) 2018 Intel Corporation
+//
+// Licensed 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.
+*/
+/// \file PerformProbe.cpp
+#include "EntityManager.hpp"
+
+#include <boost/algorithm/string/replace.hpp>
+
+#include <regex>
+
+constexpr const bool debug = false;
+
+/* Keep this in sync with EntityManager.cpp */
+static const boost::container::flat_map<const char*, probe_type_codes, CmpStr>
+    probeTypes{{{"FALSE", probe_type_codes::FALSE_T},
+                {"TRUE", probe_type_codes::TRUE_T},
+                {"AND", probe_type_codes::AND},
+                {"OR", probe_type_codes::OR},
+                {"FOUND", probe_type_codes::FOUND},
+                {"MATCH_ONE", probe_type_codes::MATCH_ONE}}};
+
+// probes dbus interface dictionary for a key with a value that matches a regex
+// When an interface passes a probe, also save its D-Bus path with it.
+bool probeDbus(const std::string& interface,
+               const std::map<std::string, nlohmann::json>& matches,
+               FoundDeviceT& devices, const std::shared_ptr<PerformScan>& scan,
+               bool& foundProbe)
+{
+    bool foundMatch = false;
+    foundProbe = false;
+
+    for (const auto& [path, interfaces] : scan->dbusProbeObjects)
+    {
+        auto it = interfaces.find(interface);
+        if (it == interfaces.end())
+        {
+            continue;
+        }
+
+        foundProbe = true;
+
+        bool deviceMatches = true;
+        const boost::container::flat_map<std::string, BasicVariantType>&
+            properties = it->second;
+
+        for (const auto& [matchProp, matchJSON] : matches)
+        {
+            auto deviceValue = properties.find(matchProp);
+            if (deviceValue != properties.end())
+            {
+                deviceMatches =
+                    deviceMatches && matchProbe(matchJSON, deviceValue->second);
+            }
+            else
+            {
+                // Move on to the next DBus path
+                deviceMatches = false;
+                break;
+            }
+        }
+        if (deviceMatches)
+        {
+            if constexpr (debug)
+            {
+                std::cerr << "probeDBus: Found probe match on " << path << " "
+                          << interface << "\n";
+            }
+            devices.emplace_back(properties, path);
+            foundMatch = true;
+        }
+    }
+    return foundMatch;
+}
+
+// default probe entry point, iterates a list looking for specific types to
+// call specific probe functions
+bool probe(const std::vector<std::string>& probeCommand,
+           const std::shared_ptr<PerformScan>& scan, FoundDeviceT& foundDevs)
+{
+    const static std::regex command(R"(\((.*)\))");
+    std::smatch match;
+    bool ret = false;
+    bool matchOne = false;
+    bool cur = true;
+    probe_type_codes lastCommand = probe_type_codes::FALSE_T;
+    bool first = true;
+
+    for (auto& probe : probeCommand)
+    {
+        bool foundProbe = false;
+        boost::container::flat_map<const char*, probe_type_codes,
+                                   CmpStr>::const_iterator probeType;
+
+        for (probeType = probeTypes.begin(); probeType != probeTypes.end();
+             ++probeType)
+        {
+            if (probe.find(probeType->first) != std::string::npos)
+            {
+                foundProbe = true;
+                break;
+            }
+        }
+        if (foundProbe)
+        {
+            switch (probeType->second)
+            {
+                case probe_type_codes::FALSE_T:
+                {
+                    cur = false;
+                    break;
+                }
+                case probe_type_codes::TRUE_T:
+                {
+                    cur = true;
+                    break;
+                }
+                case probe_type_codes::MATCH_ONE:
+                {
+                    // set current value to last, this probe type shouldn't
+                    // affect the outcome
+                    cur = ret;
+                    matchOne = true;
+                    break;
+                }
+                /*case probe_type_codes::AND:
+                  break;
+                case probe_type_codes::OR:
+                  break;
+                  // these are no-ops until the last command switch
+                  */
+                case probe_type_codes::FOUND:
+                {
+                    if (!std::regex_search(probe, match, command))
+                    {
+                        std::cerr << "found probe syntax error " << probe
+                                  << "\n";
+                        return false;
+                    }
+                    std::string commandStr = *(match.begin() + 1);
+                    boost::replace_all(commandStr, "'", "");
+                    cur = (std::find(scan->passedProbes.begin(),
+                                     scan->passedProbes.end(),
+                                     commandStr) != scan->passedProbes.end());
+                    break;
+                }
+                default:
+                {
+                    break;
+                }
+            }
+        }
+        // look on dbus for object
+        else
+        {
+            if (!std::regex_search(probe, match, command))
+            {
+                std::cerr << "dbus probe syntax error " << probe << "\n";
+                return false;
+            }
+            std::string commandStr = *(match.begin() + 1);
+            // convert single ticks and single slashes into legal json
+            boost::replace_all(commandStr, "'", "\"");
+            boost::replace_all(commandStr, R"(\)", R"(\\)");
+            auto json = nlohmann::json::parse(commandStr, nullptr, false);
+            if (json.is_discarded())
+            {
+                std::cerr << "dbus command syntax error " << commandStr << "\n";
+                return false;
+            }
+            // we can match any (string, variant) property. (string, string)
+            // does a regex
+            std::map<std::string, nlohmann::json> dbusProbeMap =
+                json.get<std::map<std::string, nlohmann::json>>();
+            auto findStart = probe.find('(');
+            if (findStart == std::string::npos)
+            {
+                return false;
+            }
+            std::string probeInterface = probe.substr(0, findStart);
+            cur = probeDbus(probeInterface, dbusProbeMap, foundDevs, scan,
+                            foundProbe);
+        }
+
+        // some functions like AND and OR only take affect after the
+        // fact
+        if (lastCommand == probe_type_codes::AND)
+        {
+            ret = cur && ret;
+        }
+        else if (lastCommand == probe_type_codes::OR)
+        {
+            ret = cur || ret;
+        }
+
+        if (first)
+        {
+            ret = cur;
+            first = false;
+        }
+        lastCommand = probeType != probeTypes.end() ? probeType->second
+                                                    : probe_type_codes::FALSE_T;
+    }
+
+    // probe passed, but empty device
+    if (ret && foundDevs.size() == 0)
+    {
+        foundDevs.emplace_back(
+            boost::container::flat_map<std::string, BasicVariantType>{},
+            std::string{});
+    }
+    if (matchOne && ret)
+    {
+        // match the last one
+        auto last = foundDevs.back();
+        foundDevs.clear();
+
+        foundDevs.emplace_back(std::move(last));
+    }
+    return ret;
+}
+
+PerformProbe::PerformProbe(
+    const std::vector<std::string>& probeCommand,
+    std::shared_ptr<PerformScan>& scanPtr,
+    std::function<void(FoundDeviceT&, const DBusProbeObjectT&)>&& callback) :
+    _probeCommand(probeCommand),
+    scan(scanPtr), _callback(std::move(callback))
+{}
+PerformProbe::~PerformProbe()
+{
+    FoundDeviceT foundDevs;
+    if (probe(_probeCommand, scan, foundDevs))
+    {
+        _callback(foundDevs, scan->dbusProbeObjects);
+    }
+}
diff --git a/src/meson.build b/src/meson.build
index bab416c..5add400 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -4,6 +4,7 @@
     'entity-manager',
     'EntityManager.cpp',
     'PerformScan.cpp',
+    'PerformProbe.cpp',
     'Overlay.cpp',
     'Utils.cpp',
     cpp_args: cpp_args + ['-DBOOST_ASIO_DISABLE_THREADS'],
