diff --git a/src/entity_manager/configuration.cpp b/src/entity_manager/configuration.cpp
new file mode 100644
index 0000000..5663ec8
--- /dev/null
+++ b/src/entity_manager/configuration.cpp
@@ -0,0 +1,197 @@
+#include "configuration.hpp"
+
+#include "../utils.hpp"
+#include "perform_probe.hpp"
+
+#include <nlohmann/json.hpp>
+#include <valijson/adapters/nlohmann_json_adapter.hpp>
+#include <valijson/schema.hpp>
+#include <valijson/schema_parser.hpp>
+#include <valijson/validator.hpp>
+
+#include <filesystem>
+#include <fstream>
+#include <iostream>
+#include <list>
+#include <string>
+#include <vector>
+
+namespace configuration
+{
+// writes output files to persist data
+bool writeJsonFiles(const nlohmann::json& systemConfiguration)
+{
+    std::filesystem::create_directory(configurationOutDir);
+    std::ofstream output(currentConfiguration);
+    if (!output.good())
+    {
+        return false;
+    }
+    output << systemConfiguration.dump(4);
+    output.close();
+    return true;
+}
+
+// reads json files out of the filesystem
+bool loadConfigurations(std::list<nlohmann::json>& configurations)
+{
+    // find configuration files
+    std::vector<std::filesystem::path> jsonPaths;
+    if (!findFiles(
+            std::vector<std::filesystem::path>{configurationDirectory,
+                                               hostConfigurationDirectory},
+            R"(.*\.json)", jsonPaths))
+    {
+        std::cerr << "Unable to find any configuration files in "
+                  << configurationDirectory << "\n";
+        return false;
+    }
+
+    std::ifstream schemaStream(
+        std::string(schemaDirectory) + "/" + globalSchema);
+    if (!schemaStream.good())
+    {
+        std::cerr
+            << "Cannot open schema file,  cannot validate JSON, exiting\n\n";
+        std::exit(EXIT_FAILURE);
+        return false;
+    }
+    nlohmann::json schema =
+        nlohmann::json::parse(schemaStream, nullptr, false, true);
+    if (schema.is_discarded())
+    {
+        std::cerr
+            << "Illegal schema file detected, cannot validate JSON, exiting\n";
+        std::exit(EXIT_FAILURE);
+        return false;
+    }
+
+    for (auto& jsonPath : jsonPaths)
+    {
+        std::ifstream jsonStream(jsonPath.c_str());
+        if (!jsonStream.good())
+        {
+            std::cerr << "unable to open " << jsonPath.string() << "\n";
+            continue;
+        }
+        auto data = nlohmann::json::parse(jsonStream, nullptr, false, true);
+        if (data.is_discarded())
+        {
+            std::cerr << "syntax error in " << jsonPath.string() << "\n";
+            continue;
+        }
+        /*
+        * todo(james): reenable this once less things are in flight
+        *
+        if (!validateJson(schema, data))
+        {
+            std::cerr << "Error validating " << jsonPath.string() << "\n";
+            continue;
+        }
+        */
+
+        if (data.type() == nlohmann::json::value_t::array)
+        {
+            for (auto& d : data)
+            {
+                configurations.emplace_back(d);
+            }
+        }
+        else
+        {
+            configurations.emplace_back(data);
+        }
+    }
+    return true;
+}
+
+// Iterate over new configuration and erase items from old configuration.
+void deriveNewConfiguration(const nlohmann::json& oldConfiguration,
+                            nlohmann::json& newConfiguration)
+{
+    for (auto it = newConfiguration.begin(); it != newConfiguration.end();)
+    {
+        auto findKey = oldConfiguration.find(it.key());
+        if (findKey != oldConfiguration.end())
+        {
+            it = newConfiguration.erase(it);
+        }
+        else
+        {
+            it++;
+        }
+    }
+}
+
+// validates a given input(configuration) with a given json schema file.
+bool validateJson(const nlohmann::json& schemaFile, const nlohmann::json& input)
+{
+    valijson::Schema schema;
+    valijson::SchemaParser parser;
+    valijson::adapters::NlohmannJsonAdapter schemaAdapter(schemaFile);
+    parser.populateSchema(schemaAdapter, schema);
+    valijson::Validator validator;
+    valijson::adapters::NlohmannJsonAdapter targetAdapter(input);
+    return validator.validate(schema, targetAdapter, nullptr);
+}
+
+// Extract the D-Bus interfaces to probe from the JSON config files.
+std::set<std::string> getProbeInterfaces()
+{
+    std::set<std::string> interfaces;
+    std::list<nlohmann::json> configurations;
+    if (!configuration::loadConfigurations(configurations))
+    {
+        return interfaces;
+    }
+
+    for (auto it = configurations.begin(); it != configurations.end();)
+    {
+        auto findProbe = it->find("Probe");
+        if (findProbe == it->end())
+        {
+            std::cerr << "configuration file missing probe:\n " << *it << "\n";
+            it++;
+            continue;
+        }
+
+        nlohmann::json probeCommand;
+        if ((*findProbe).type() != nlohmann::json::value_t::array)
+        {
+            probeCommand = nlohmann::json::array();
+            probeCommand.push_back(*findProbe);
+        }
+        else
+        {
+            probeCommand = *findProbe;
+        }
+
+        for (const nlohmann::json& probeJson : probeCommand)
+        {
+            const std::string* probe = probeJson.get_ptr<const std::string*>();
+            if (probe == nullptr)
+            {
+                std::cerr << "Probe statement wasn't a string, can't parse";
+                continue;
+            }
+            // Skip it if the probe cmd doesn't contain an interface.
+            if (probe::findProbeType(*probe))
+            {
+                continue;
+            }
+
+            // syntax requires probe before first open brace
+            auto findStart = probe->find('(');
+            if (findStart != std::string::npos)
+            {
+                std::string interface = probe->substr(0, findStart);
+                interfaces.emplace(interface);
+            }
+        }
+        it++;
+    }
+
+    return interfaces;
+}
+
+} // namespace configuration
diff --git a/src/entity_manager/configuration.hpp b/src/entity_manager/configuration.hpp
new file mode 100644
index 0000000..b3b2cdc
--- /dev/null
+++ b/src/entity_manager/configuration.hpp
@@ -0,0 +1,45 @@
+#pragma once
+
+#include <nlohmann/json.hpp>
+
+#include <list>
+#include <set>
+
+namespace configuration
+{
+constexpr const char* globalSchema = "global.json";
+constexpr const char* hostConfigurationDirectory = SYSCONF_DIR "configurations";
+constexpr const char* configurationDirectory = PACKAGE_DIR "configurations";
+constexpr const char* currentConfiguration = "/var/configuration/system.json";
+constexpr const char* schemaDirectory = PACKAGE_DIR "configurations/schemas";
+
+bool writeJsonFiles(const nlohmann::json& systemConfiguration);
+
+bool loadConfigurations(std::list<nlohmann::json>& configurations);
+
+template <typename JsonType>
+bool setJsonFromPointer(const std::string& ptrStr, const JsonType& value,
+                        nlohmann::json& systemConfiguration)
+{
+    try
+    {
+        nlohmann::json::json_pointer ptr(ptrStr);
+        nlohmann::json& ref = systemConfiguration[ptr];
+        ref = value;
+        return true;
+    }
+    catch (const std::out_of_range&)
+    {
+        return false;
+    }
+}
+
+void deriveNewConfiguration(const nlohmann::json& oldConfiguration,
+                            nlohmann::json& newConfiguration);
+
+bool validateJson(const nlohmann::json& schemaFile,
+                  const nlohmann::json& input);
+
+std::set<std::string> getProbeInterfaces();
+
+} // namespace configuration
diff --git a/src/entity_manager/dbus_interface.cpp b/src/entity_manager/dbus_interface.cpp
new file mode 100644
index 0000000..f0c904c
--- /dev/null
+++ b/src/entity_manager/dbus_interface.cpp
@@ -0,0 +1,395 @@
+#include "dbus_interface.hpp"
+
+#include "../utils.hpp"
+#include "perform_probe.hpp"
+
+#include <boost/algorithm/string/case_conv.hpp>
+#include <boost/container/flat_map.hpp>
+
+#include <regex>
+#include <string>
+#include <vector>
+
+using JsonVariantType =
+    std::variant<std::vector<std::string>, std::vector<double>, std::string,
+                 int64_t, uint64_t, double, int32_t, uint32_t, int16_t,
+                 uint16_t, uint8_t, bool>;
+
+namespace dbus_interface
+{
+
+const std::regex illegalDbusPathRegex("[^A-Za-z0-9_.]");
+const std::regex illegalDbusMemberRegex("[^A-Za-z0-9_]");
+
+// NOLINTBEGIN(cppcoreguidelines-avoid-non-const-global-variables)
+// store reference to all interfaces so we can destroy them later
+boost::container::flat_map<
+    std::string, std::vector<std::weak_ptr<sdbusplus::asio::dbus_interface>>>
+    inventory;
+// NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables)
+
+void tryIfaceInitialize(std::shared_ptr<sdbusplus::asio::dbus_interface>& iface)
+{
+    try
+    {
+        iface->initialize();
+    }
+    catch (std::exception& e)
+    {
+        std::cerr << "Unable to initialize dbus interface : " << e.what()
+                  << "\n"
+                  << "object Path : " << iface->get_object_path() << "\n"
+                  << "interface name : " << iface->get_interface_name() << "\n";
+    }
+}
+
+std::shared_ptr<sdbusplus::asio::dbus_interface> createInterface(
+    sdbusplus::asio::object_server& objServer, const std::string& path,
+    const std::string& interface, const std::string& parent, bool checkNull)
+{
+    // on first add we have no reason to check for null before add, as there
+    // won't be any. For dynamically added interfaces, we check for null so that
+    // a constant delete/add will not create a memory leak
+
+    auto ptr = objServer.add_interface(path, interface);
+    auto& dataVector = inventory[parent];
+    if (checkNull)
+    {
+        auto it = std::find_if(dataVector.begin(), dataVector.end(),
+                               [](const auto& p) { return p.expired(); });
+        if (it != dataVector.end())
+        {
+            *it = ptr;
+            return ptr;
+        }
+    }
+    dataVector.emplace_back(ptr);
+    return ptr;
+}
+
+void createDeleteObjectMethod(
+    const std::string& jsonPointerPath,
+    const std::shared_ptr<sdbusplus::asio::dbus_interface>& iface,
+    sdbusplus::asio::object_server& objServer,
+    nlohmann::json& systemConfiguration)
+{
+    std::weak_ptr<sdbusplus::asio::dbus_interface> interface = iface;
+    iface->register_method(
+        "Delete", [&objServer, &systemConfiguration, interface,
+                   jsonPointerPath{std::string(jsonPointerPath)}]() {
+            std::shared_ptr<sdbusplus::asio::dbus_interface> dbusInterface =
+                interface.lock();
+            if (!dbusInterface)
+            {
+                // this technically can't happen as the pointer is pointing to
+                // us
+                throw DBusInternalError();
+            }
+            nlohmann::json::json_pointer ptr(jsonPointerPath);
+            systemConfiguration[ptr] = nullptr;
+
+            // todo(james): dig through sdbusplus to find out why we can't
+            // delete it in a method call
+            boost::asio::post(io, [&objServer, dbusInterface]() mutable {
+                objServer.remove_interface(dbusInterface);
+            });
+
+            if (!configuration::writeJsonFiles(systemConfiguration))
+            {
+                std::cerr << "error setting json file\n";
+                throw DBusInternalError();
+            }
+        });
+}
+
+// adds simple json types to interface's properties
+void populateInterfaceFromJson(
+    nlohmann::json& systemConfiguration, const std::string& jsonPointerPath,
+    std::shared_ptr<sdbusplus::asio::dbus_interface>& iface,
+    nlohmann::json& dict, sdbusplus::asio::object_server& objServer,
+    sdbusplus::asio::PropertyPermission permission)
+{
+    for (const auto& [key, value] : dict.items())
+    {
+        auto type = value.type();
+        bool array = false;
+        if (value.type() == nlohmann::json::value_t::array)
+        {
+            array = true;
+            if (value.empty())
+            {
+                continue;
+            }
+            type = value[0].type();
+            bool isLegal = true;
+            for (const auto& arrayItem : value)
+            {
+                if (arrayItem.type() != type)
+                {
+                    isLegal = false;
+                    break;
+                }
+            }
+            if (!isLegal)
+            {
+                std::cerr << "dbus format error" << value << "\n";
+                continue;
+            }
+        }
+        if (type == nlohmann::json::value_t::object)
+        {
+            continue; // handled elsewhere
+        }
+
+        std::string path = jsonPointerPath;
+        path.append("/").append(key);
+        if (permission == sdbusplus::asio::PropertyPermission::readWrite)
+        {
+            // all setable numbers are doubles as it is difficult to always
+            // create a configuration file with all whole numbers as decimals
+            // i.e. 1.0
+            if (array)
+            {
+                if (value[0].is_number())
+                {
+                    type = nlohmann::json::value_t::number_float;
+                }
+            }
+            else if (value.is_number())
+            {
+                type = nlohmann::json::value_t::number_float;
+            }
+        }
+
+        switch (type)
+        {
+            case (nlohmann::json::value_t::boolean):
+            {
+                if (array)
+                {
+                    // todo: array of bool isn't detected correctly by
+                    // sdbusplus, change it to numbers
+                    addArrayToDbus<uint64_t>(key, value, iface.get(),
+                                             permission, systemConfiguration,
+                                             path);
+                }
+
+                else
+                {
+                    addProperty(key, value.get<bool>(), iface.get(),
+                                systemConfiguration, path, permission);
+                }
+                break;
+            }
+            case (nlohmann::json::value_t::number_integer):
+            {
+                if (array)
+                {
+                    addArrayToDbus<int64_t>(key, value, iface.get(), permission,
+                                            systemConfiguration, path);
+                }
+                else
+                {
+                    addProperty(key, value.get<int64_t>(), iface.get(),
+                                systemConfiguration, path,
+                                sdbusplus::asio::PropertyPermission::readOnly);
+                }
+                break;
+            }
+            case (nlohmann::json::value_t::number_unsigned):
+            {
+                if (array)
+                {
+                    addArrayToDbus<uint64_t>(key, value, iface.get(),
+                                             permission, systemConfiguration,
+                                             path);
+                }
+                else
+                {
+                    addProperty(key, value.get<uint64_t>(), iface.get(),
+                                systemConfiguration, path,
+                                sdbusplus::asio::PropertyPermission::readOnly);
+                }
+                break;
+            }
+            case (nlohmann::json::value_t::number_float):
+            {
+                if (array)
+                {
+                    addArrayToDbus<double>(key, value, iface.get(), permission,
+                                           systemConfiguration, path);
+                }
+
+                else
+                {
+                    addProperty(key, value.get<double>(), iface.get(),
+                                systemConfiguration, path, permission);
+                }
+                break;
+            }
+            case (nlohmann::json::value_t::string):
+            {
+                if (array)
+                {
+                    addArrayToDbus<std::string>(key, value, iface.get(),
+                                                permission, systemConfiguration,
+                                                path);
+                }
+                else
+                {
+                    addProperty(key, value.get<std::string>(), iface.get(),
+                                systemConfiguration, path, permission);
+                }
+                break;
+            }
+            default:
+            {
+                std::cerr << "Unexpected json type in system configuration "
+                          << key << ": " << value.type_name() << "\n";
+                break;
+            }
+        }
+    }
+    if (permission == sdbusplus::asio::PropertyPermission::readWrite)
+    {
+        createDeleteObjectMethod(jsonPointerPath, iface, objServer,
+                                 systemConfiguration);
+    }
+    tryIfaceInitialize(iface);
+}
+
+void createAddObjectMethod(
+    const std::string& jsonPointerPath, const std::string& path,
+    nlohmann::json& systemConfiguration,
+    sdbusplus::asio::object_server& objServer, const std::string& board)
+{
+    std::shared_ptr<sdbusplus::asio::dbus_interface> iface = createInterface(
+        objServer, path, "xyz.openbmc_project.AddObject", board);
+
+    iface->register_method(
+        "AddObject",
+        [&systemConfiguration, &objServer,
+         jsonPointerPath{std::string(jsonPointerPath)}, path{std::string(path)},
+         board](const boost::container::flat_map<std::string, JsonVariantType>&
+                    data) {
+            nlohmann::json::json_pointer ptr(jsonPointerPath);
+            nlohmann::json& base = systemConfiguration[ptr];
+            auto findExposes = base.find("Exposes");
+
+            if (findExposes == base.end())
+            {
+                throw std::invalid_argument("Entity must have children.");
+            }
+
+            // this will throw invalid-argument to sdbusplus if invalid json
+            nlohmann::json newData{};
+            for (const auto& item : data)
+            {
+                nlohmann::json& newJson = newData[item.first];
+                std::visit(
+                    [&newJson](auto&& val) {
+                        newJson = std::forward<decltype(val)>(val);
+                    },
+                    item.second);
+            }
+
+            auto findName = newData.find("Name");
+            auto findType = newData.find("Type");
+            if (findName == newData.end() || findType == newData.end())
+            {
+                throw std::invalid_argument("AddObject missing Name or Type");
+            }
+            const std::string* type = findType->get_ptr<const std::string*>();
+            const std::string* name = findName->get_ptr<const std::string*>();
+            if (type == nullptr || name == nullptr)
+            {
+                throw std::invalid_argument("Type and Name must be a string.");
+            }
+
+            bool foundNull = false;
+            size_t lastIndex = 0;
+            // we add in the "exposes"
+            for (const auto& expose : *findExposes)
+            {
+                if (expose.is_null())
+                {
+                    foundNull = true;
+                    continue;
+                }
+
+                if (expose["Name"] == *name && expose["Type"] == *type)
+                {
+                    throw std::invalid_argument(
+                        "Field already in JSON, not adding");
+                }
+
+                if (foundNull)
+                {
+                    continue;
+                }
+
+                lastIndex++;
+            }
+
+            std::ifstream schemaFile(
+                std::string(configuration::schemaDirectory) + "/" +
+                boost::to_lower_copy(*type) + ".json");
+            // todo(james) we might want to also make a list of 'can add'
+            // interfaces but for now I think the assumption if there is a
+            // schema avaliable that it is allowed to update is fine
+            if (!schemaFile.good())
+            {
+                throw std::invalid_argument(
+                    "No schema avaliable, cannot validate.");
+            }
+            nlohmann::json schema =
+                nlohmann::json::parse(schemaFile, nullptr, false, true);
+            if (schema.is_discarded())
+            {
+                std::cerr << "Schema not legal" << *type << ".json\n";
+                throw DBusInternalError();
+            }
+            if (!configuration::validateJson(schema, newData))
+            {
+                throw std::invalid_argument("Data does not match schema");
+            }
+            if (foundNull)
+            {
+                findExposes->at(lastIndex) = newData;
+            }
+            else
+            {
+                findExposes->push_back(newData);
+            }
+            if (!configuration::writeJsonFiles(systemConfiguration))
+            {
+                std::cerr << "Error writing json files\n";
+                throw DBusInternalError();
+            }
+            std::string dbusName = *name;
+
+            std::regex_replace(dbusName.begin(), dbusName.begin(),
+                               dbusName.end(), illegalDbusMemberRegex, "_");
+
+            std::shared_ptr<sdbusplus::asio::dbus_interface> interface =
+                createInterface(objServer, path + "/" + dbusName,
+                                "xyz.openbmc_project.Configuration." + *type,
+                                board, true);
+            // permission is read-write, as since we just created it, must be
+            // runtime modifiable
+            populateInterfaceFromJson(
+                systemConfiguration,
+                jsonPointerPath + "/Exposes/" + std::to_string(lastIndex),
+                interface, newData, objServer,
+                sdbusplus::asio::PropertyPermission::readWrite);
+        });
+    tryIfaceInitialize(iface);
+}
+
+std::vector<std::weak_ptr<sdbusplus::asio::dbus_interface>>&
+    getDeviceInterfaces(const nlohmann::json& device)
+{
+    return inventory[device["Name"].get<std::string>()];
+}
+
+} // namespace dbus_interface
diff --git a/src/entity_manager/dbus_interface.hpp b/src/entity_manager/dbus_interface.hpp
new file mode 100644
index 0000000..35ea742
--- /dev/null
+++ b/src/entity_manager/dbus_interface.hpp
@@ -0,0 +1,123 @@
+#pragma once
+
+#include "configuration.hpp"
+
+#include <nlohmann/json.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+
+#include <iostream>
+#include <set>
+#include <vector>
+
+namespace dbus_interface
+{
+void tryIfaceInitialize(
+    std::shared_ptr<sdbusplus::asio::dbus_interface>& iface);
+
+std::shared_ptr<sdbusplus::asio::dbus_interface> createInterface(
+    sdbusplus::asio::object_server& objServer, const std::string& path,
+    const std::string& interface, const std::string& parent,
+    bool checkNull = false);
+
+template <typename PropertyType>
+void addArrayToDbus(const std::string& name, const nlohmann::json& array,
+                    sdbusplus::asio::dbus_interface* iface,
+                    sdbusplus::asio::PropertyPermission permission,
+                    nlohmann::json& systemConfiguration,
+                    const std::string& jsonPointerString)
+{
+    std::vector<PropertyType> values;
+    for (const auto& property : array)
+    {
+        auto ptr = property.get_ptr<const PropertyType*>();
+        if (ptr != nullptr)
+        {
+            values.emplace_back(*ptr);
+        }
+    }
+
+    if (permission == sdbusplus::asio::PropertyPermission::readOnly)
+    {
+        iface->register_property(name, values);
+    }
+    else
+    {
+        iface->register_property(
+            name, values,
+            [&systemConfiguration,
+             jsonPointerString{std::string(jsonPointerString)}](
+                const std::vector<PropertyType>& newVal,
+                std::vector<PropertyType>& val) {
+                val = newVal;
+                if (!configuration::setJsonFromPointer(jsonPointerString, val,
+                                                       systemConfiguration))
+                {
+                    std::cerr << "error setting json field\n";
+                    return -1;
+                }
+                if (!configuration::writeJsonFiles(systemConfiguration))
+                {
+                    std::cerr << "error setting json file\n";
+                    return -1;
+                }
+                return 1;
+            });
+    }
+}
+
+template <typename PropertyType>
+void addProperty(const std::string& name, const PropertyType& value,
+                 sdbusplus::asio::dbus_interface* iface,
+                 nlohmann::json& systemConfiguration,
+                 const std::string& jsonPointerString,
+                 sdbusplus::asio::PropertyPermission permission)
+{
+    if (permission == sdbusplus::asio::PropertyPermission::readOnly)
+    {
+        iface->register_property(name, value);
+        return;
+    }
+    iface->register_property(
+        name, value,
+        [&systemConfiguration,
+         jsonPointerString{std::string(jsonPointerString)}](
+            const PropertyType& newVal, PropertyType& val) {
+            val = newVal;
+            if (!configuration::setJsonFromPointer(jsonPointerString, val,
+                                                   systemConfiguration))
+            {
+                std::cerr << "error setting json field\n";
+                return -1;
+            }
+            if (!configuration::writeJsonFiles(systemConfiguration))
+            {
+                std::cerr << "error setting json file\n";
+                return -1;
+            }
+            return 1;
+        });
+}
+
+void createDeleteObjectMethod(
+    const std::string& jsonPointerPath,
+    const std::shared_ptr<sdbusplus::asio::dbus_interface>& iface,
+    sdbusplus::asio::object_server& objServer,
+    nlohmann::json& systemConfiguration);
+
+void populateInterfaceFromJson(
+    nlohmann::json& systemConfiguration, const std::string& jsonPointerPath,
+    std::shared_ptr<sdbusplus::asio::dbus_interface>& iface,
+    nlohmann::json& dict, sdbusplus::asio::object_server& objServer,
+    sdbusplus::asio::PropertyPermission permission =
+        sdbusplus::asio::PropertyPermission::readOnly);
+
+void createAddObjectMethod(
+    const std::string& jsonPointerPath, const std::string& path,
+    nlohmann::json& systemConfiguration,
+    sdbusplus::asio::object_server& objServer, const std::string& board);
+
+std::vector<std::weak_ptr<sdbusplus::asio::dbus_interface>>&
+    getDeviceInterfaces(const nlohmann::json& device);
+
+} // namespace dbus_interface
diff --git a/src/entity_manager/devices.hpp b/src/entity_manager/devices.hpp
new file mode 100644
index 0000000..28028bb
--- /dev/null
+++ b/src/entity_manager/devices.hpp
@@ -0,0 +1,206 @@
+/*
+// 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 devices.hpp
+
+#pragma once
+#include <boost/container/flat_map.hpp>
+
+namespace devices
+{
+
+struct CmpStr
+{
+    bool operator()(const char* a, const char* b) const
+    {
+        return std::strcmp(a, b) < 0;
+    }
+};
+
+// I2C device drivers may create a /hwmon subdirectory. For example the tmp75
+// driver creates a /sys/bus/i2c/devices/<busnum>-<i2caddr>/hwmon
+// directory. The sensor code relies on the presence of the /hwmon
+// subdirectory to collect sensor readings. Initialization of this subdir is
+// not reliable. I2C devices flagged with hasHWMonDir are tested for correct
+// initialization, and when a failure is detected the device is deleted, and
+// then recreated. The default is to retry 5 times before moving to the next
+// device.
+
+// Devices such as I2C EEPROMs do not generate this file structure. These
+// kinds of devices are flagged using the noHWMonDir enumeration. The
+// expectation is they are created correctly on the first attempt.
+
+// This enumeration class exists to reduce copy/paste errors. It is easy to
+// overlook the trailing parameter in the ExportTemplate structure when it is
+// a simple boolean.
+enum class createsHWMon : bool
+{
+    noHWMonDir,
+    hasHWMonDir
+};
+
+struct ExportTemplate
+{
+    ExportTemplate(const char* params, const char* bus, const char* constructor,
+                   const char* destructor, createsHWMon hasHWMonDir) :
+        parameters(params), busPath(bus), add(constructor), remove(destructor),
+        hasHWMonDir(hasHWMonDir) {};
+    const char* parameters;
+    const char* busPath;
+    const char* add;
+    const char* remove;
+    createsHWMon hasHWMonDir;
+};
+
+const boost::container::flat_map<const char*, ExportTemplate, CmpStr>
+    exportTemplates{
+        {{"EEPROM_24C01",
+          ExportTemplate("24c01 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::noHWMonDir)},
+         {"EEPROM_24C02",
+          ExportTemplate("24c02 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::noHWMonDir)},
+         {"EEPROM_24C04",
+          ExportTemplate("24c04 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::noHWMonDir)},
+         {"EEPROM_24C08",
+          ExportTemplate("24c08 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::noHWMonDir)},
+         {"EEPROM_24C16",
+          ExportTemplate("24c16 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::noHWMonDir)},
+         {"EEPROM_24C32",
+          ExportTemplate("24c32 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::noHWMonDir)},
+         {"EEPROM_24C64",
+          ExportTemplate("24c64 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::noHWMonDir)},
+         {"EEPROM_24C128",
+          ExportTemplate("24c128 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::noHWMonDir)},
+         {"EEPROM_24C256",
+          ExportTemplate("24c256 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::noHWMonDir)},
+         {"ADS1015",
+          ExportTemplate("ads1015 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::noHWMonDir)},
+         {"ADS7828",
+          ExportTemplate("ads7828 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::noHWMonDir)},
+         {"EEPROM",
+          ExportTemplate("eeprom $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::noHWMonDir)},
+         {"Gpio", ExportTemplate("$Index", "/sys/class/gpio", "export",
+                                 "unexport", createsHWMon::noHWMonDir)},
+         {"IPSPS1",
+          ExportTemplate("ipsps1 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::hasHWMonDir)},
+         {"MAX34440",
+          ExportTemplate("max34440 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::hasHWMonDir)},
+         {"PCA9537",
+          ExportTemplate("pca9537 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::noHWMonDir)},
+         {"PCA9542Mux",
+          ExportTemplate("pca9542 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::noHWMonDir)},
+         {"PCA9543Mux",
+          ExportTemplate("pca9543 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::noHWMonDir)},
+         {"PCA9544Mux",
+          ExportTemplate("pca9544 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::noHWMonDir)},
+         {"PCA9545Mux",
+          ExportTemplate("pca9545 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::noHWMonDir)},
+         {"PCA9546Mux",
+          ExportTemplate("pca9546 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::noHWMonDir)},
+         {"PCA9547Mux",
+          ExportTemplate("pca9547 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::noHWMonDir)},
+         {"PCA9548Mux",
+          ExportTemplate("pca9548 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::noHWMonDir)},
+         {"PCA9846Mux",
+          ExportTemplate("pca9846 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::noHWMonDir)},
+         {"PCA9847Mux",
+          ExportTemplate("pca9847 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::noHWMonDir)},
+         {"PCA9848Mux",
+          ExportTemplate("pca9848 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::noHWMonDir)},
+         {"PCA9849Mux",
+          ExportTemplate("pca9849 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::noHWMonDir)},
+         {"SIC450",
+          ExportTemplate("sic450 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::hasHWMonDir)},
+         {"Q50SN12072",
+          ExportTemplate("q50sn12072 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::hasHWMonDir)},
+         {"MAX31790",
+          ExportTemplate("max31790 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::hasHWMonDir)},
+         {"PIC32", ExportTemplate("pic32 $Address",
+                                  "/sys/bus/i2c/devices/i2c-$Bus", "new_device",
+                                  "delete_device", createsHWMon::hasHWMonDir)},
+         {"INA226",
+          ExportTemplate("ina226 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::hasHWMonDir)},
+         {"RAA229620",
+          ExportTemplate("raa229620 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::hasHWMonDir)},
+         {"RAA229621",
+          ExportTemplate("raa229621 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::hasHWMonDir)},
+         {"PIC32",
+          ExportTemplate("pic32 $Address", "/sys/bus/i2c/devices/i2c-$Bus",
+                         "new_device", "delete_device",
+                         createsHWMon::hasHWMonDir)}}};
+} // namespace devices
diff --git a/src/entity_manager/entity_manager.cpp b/src/entity_manager/entity_manager.cpp
new file mode 100644
index 0000000..5aa5380
--- /dev/null
+++ b/src/entity_manager/entity_manager.cpp
@@ -0,0 +1,709 @@
+/*
+// 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 entity_manager.cpp
+
+#include "entity_manager.hpp"
+
+#include "../utils.hpp"
+#include "../variant_visitors.hpp"
+#include "configuration.hpp"
+#include "dbus_interface.hpp"
+#include "overlay.hpp"
+#include "perform_scan.hpp"
+#include "topology.hpp"
+
+#include <boost/algorithm/string/case_conv.hpp>
+#include <boost/algorithm/string/classification.hpp>
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/algorithm/string/replace.hpp>
+#include <boost/algorithm/string/split.hpp>
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/post.hpp>
+#include <boost/asio/steady_timer.hpp>
+#include <boost/container/flat_map.hpp>
+#include <boost/container/flat_set.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <nlohmann/json.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+
+#include <charconv>
+#include <filesystem>
+#include <fstream>
+#include <functional>
+#include <iostream>
+#include <map>
+#include <regex>
+#include <variant>
+constexpr const char* tempConfigDir = "/tmp/configuration/";
+constexpr const char* lastConfiguration = "/tmp/configuration/last.json";
+
+static constexpr std::array<const char*, 6> settableInterfaces = {
+    "FanProfile", "Pid", "Pid.Zone", "Stepwise", "Thresholds", "Polling"};
+
+// NOLINTBEGIN(cppcoreguidelines-avoid-non-const-global-variables)
+
+// todo: pass this through nicer
+std::shared_ptr<sdbusplus::asio::connection> systemBus;
+nlohmann::json lastJson;
+Topology topology;
+
+boost::asio::io_context io;
+// NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables)
+
+const std::regex illegalDbusPathRegex("[^A-Za-z0-9_.]");
+const std::regex illegalDbusMemberRegex("[^A-Za-z0-9_]");
+
+sdbusplus::asio::PropertyPermission getPermission(const std::string& interface)
+{
+    return std::find(settableInterfaces.begin(), settableInterfaces.end(),
+                     interface) != settableInterfaces.end()
+               ? sdbusplus::asio::PropertyPermission::readWrite
+               : sdbusplus::asio::PropertyPermission::readOnly;
+}
+
+void postToDbus(const nlohmann::json& newConfiguration,
+                nlohmann::json& systemConfiguration,
+                sdbusplus::asio::object_server& objServer)
+
+{
+    std::map<std::string, std::string> newBoards; // path -> name
+
+    // iterate through boards
+    for (const auto& [boardId, boardConfig] : newConfiguration.items())
+    {
+        std::string boardName = boardConfig["Name"];
+        std::string boardNameOrig = boardConfig["Name"];
+        std::string jsonPointerPath = "/" + boardId;
+        // loop through newConfiguration, but use values from system
+        // configuration to be able to modify via dbus later
+        auto boardValues = systemConfiguration[boardId];
+        auto findBoardType = boardValues.find("Type");
+        std::string boardType;
+        if (findBoardType != boardValues.end() &&
+            findBoardType->type() == nlohmann::json::value_t::string)
+        {
+            boardType = findBoardType->get<std::string>();
+            std::regex_replace(boardType.begin(), boardType.begin(),
+                               boardType.end(), illegalDbusMemberRegex, "_");
+        }
+        else
+        {
+            std::cerr << "Unable to find type for " << boardName
+                      << " reverting to Chassis.\n";
+            boardType = "Chassis";
+        }
+        std::string boardtypeLower = boost::algorithm::to_lower_copy(boardType);
+
+        std::regex_replace(boardName.begin(), boardName.begin(),
+                           boardName.end(), illegalDbusMemberRegex, "_");
+        std::string boardPath = "/xyz/openbmc_project/inventory/system/";
+        boardPath += boardtypeLower;
+        boardPath += "/";
+        boardPath += boardName;
+
+        std::shared_ptr<sdbusplus::asio::dbus_interface> inventoryIface =
+            dbus_interface::createInterface(
+                objServer, boardPath, "xyz.openbmc_project.Inventory.Item",
+                boardName);
+
+        std::shared_ptr<sdbusplus::asio::dbus_interface> boardIface =
+            dbus_interface::createInterface(
+                objServer, boardPath,
+                "xyz.openbmc_project.Inventory.Item." + boardType,
+                boardNameOrig);
+
+        dbus_interface::createAddObjectMethod(
+            jsonPointerPath, boardPath, systemConfiguration, objServer,
+            boardNameOrig);
+
+        dbus_interface::populateInterfaceFromJson(
+            systemConfiguration, jsonPointerPath, boardIface, boardValues,
+            objServer);
+        jsonPointerPath += "/";
+        // iterate through board properties
+        for (const auto& [propName, propValue] : boardValues.items())
+        {
+            if (propValue.type() == nlohmann::json::value_t::object)
+            {
+                std::shared_ptr<sdbusplus::asio::dbus_interface> iface =
+                    dbus_interface::createInterface(objServer, boardPath,
+                                                    propName, boardNameOrig);
+
+                dbus_interface::populateInterfaceFromJson(
+                    systemConfiguration, jsonPointerPath + propName, iface,
+                    propValue, objServer);
+            }
+        }
+
+        auto exposes = boardValues.find("Exposes");
+        if (exposes == boardValues.end())
+        {
+            continue;
+        }
+        // iterate through exposes
+        jsonPointerPath += "Exposes/";
+
+        // store the board level pointer so we can modify it on the way down
+        std::string jsonPointerPathBoard = jsonPointerPath;
+        size_t exposesIndex = -1;
+        for (auto& item : *exposes)
+        {
+            exposesIndex++;
+            jsonPointerPath = jsonPointerPathBoard;
+            jsonPointerPath += std::to_string(exposesIndex);
+
+            auto findName = item.find("Name");
+            if (findName == item.end())
+            {
+                std::cerr << "cannot find name in field " << item << "\n";
+                continue;
+            }
+            auto findStatus = item.find("Status");
+            // if status is not found it is assumed to be status = 'okay'
+            if (findStatus != item.end())
+            {
+                if (*findStatus == "disabled")
+                {
+                    continue;
+                }
+            }
+            auto findType = item.find("Type");
+            std::string itemType;
+            if (findType != item.end())
+            {
+                itemType = findType->get<std::string>();
+                std::regex_replace(itemType.begin(), itemType.begin(),
+                                   itemType.end(), illegalDbusPathRegex, "_");
+            }
+            else
+            {
+                itemType = "unknown";
+            }
+            std::string itemName = findName->get<std::string>();
+            std::regex_replace(itemName.begin(), itemName.begin(),
+                               itemName.end(), illegalDbusMemberRegex, "_");
+            std::string ifacePath = boardPath;
+            ifacePath += "/";
+            ifacePath += itemName;
+
+            if (itemType == "BMC")
+            {
+                std::shared_ptr<sdbusplus::asio::dbus_interface> bmcIface =
+                    dbus_interface::createInterface(
+                        objServer, ifacePath,
+                        "xyz.openbmc_project.Inventory.Item.Bmc",
+                        boardNameOrig);
+                dbus_interface::populateInterfaceFromJson(
+                    systemConfiguration, jsonPointerPath, bmcIface, item,
+                    objServer, getPermission(itemType));
+            }
+            else if (itemType == "System")
+            {
+                std::shared_ptr<sdbusplus::asio::dbus_interface> systemIface =
+                    dbus_interface::createInterface(
+                        objServer, ifacePath,
+                        "xyz.openbmc_project.Inventory.Item.System",
+                        boardNameOrig);
+                dbus_interface::populateInterfaceFromJson(
+                    systemConfiguration, jsonPointerPath, systemIface, item,
+                    objServer, getPermission(itemType));
+            }
+
+            for (const auto& [name, config] : item.items())
+            {
+                jsonPointerPath = jsonPointerPathBoard;
+                jsonPointerPath.append(std::to_string(exposesIndex))
+                    .append("/")
+                    .append(name);
+                if (config.type() == nlohmann::json::value_t::object)
+                {
+                    std::string ifaceName =
+                        "xyz.openbmc_project.Configuration.";
+                    ifaceName.append(itemType).append(".").append(name);
+
+                    std::shared_ptr<sdbusplus::asio::dbus_interface>
+                        objectIface = dbus_interface::createInterface(
+                            objServer, ifacePath, ifaceName, boardNameOrig);
+
+                    dbus_interface::populateInterfaceFromJson(
+                        systemConfiguration, jsonPointerPath, objectIface,
+                        config, objServer, getPermission(name));
+                }
+                else if (config.type() == nlohmann::json::value_t::array)
+                {
+                    size_t index = 0;
+                    if (config.empty())
+                    {
+                        continue;
+                    }
+                    bool isLegal = true;
+                    auto type = config[0].type();
+                    if (type != nlohmann::json::value_t::object)
+                    {
+                        continue;
+                    }
+
+                    // verify legal json
+                    for (const auto& arrayItem : config)
+                    {
+                        if (arrayItem.type() != type)
+                        {
+                            isLegal = false;
+                            break;
+                        }
+                    }
+                    if (!isLegal)
+                    {
+                        std::cerr << "dbus format error" << config << "\n";
+                        break;
+                    }
+
+                    for (auto& arrayItem : config)
+                    {
+                        std::string ifaceName =
+                            "xyz.openbmc_project.Configuration.";
+                        ifaceName.append(itemType).append(".").append(name);
+                        ifaceName.append(std::to_string(index));
+
+                        std::shared_ptr<sdbusplus::asio::dbus_interface>
+                            objectIface = dbus_interface::createInterface(
+                                objServer, ifacePath, ifaceName, boardNameOrig);
+
+                        dbus_interface::populateInterfaceFromJson(
+                            systemConfiguration,
+                            jsonPointerPath + "/" + std::to_string(index),
+                            objectIface, arrayItem, objServer,
+                            getPermission(name));
+                        index++;
+                    }
+                }
+            }
+
+            std::shared_ptr<sdbusplus::asio::dbus_interface> itemIface =
+                dbus_interface::createInterface(
+                    objServer, ifacePath,
+                    "xyz.openbmc_project.Configuration." + itemType,
+                    boardNameOrig);
+
+            dbus_interface::populateInterfaceFromJson(
+                systemConfiguration, jsonPointerPath, itemIface, item,
+                objServer, getPermission(itemType));
+
+            topology.addBoard(boardPath, boardType, boardNameOrig, item);
+        }
+
+        newBoards.emplace(boardPath, boardNameOrig);
+    }
+
+    for (const auto& [assocPath, assocPropValue] :
+         topology.getAssocs(newBoards))
+    {
+        auto findBoard = newBoards.find(assocPath);
+        if (findBoard == newBoards.end())
+        {
+            continue;
+        }
+
+        auto ifacePtr = dbus_interface::createInterface(
+            objServer, assocPath, "xyz.openbmc_project.Association.Definitions",
+            findBoard->second);
+
+        ifacePtr->register_property("Associations", assocPropValue);
+        dbus_interface::tryIfaceInitialize(ifacePtr);
+    }
+}
+
+static bool deviceRequiresPowerOn(const nlohmann::json& entity)
+{
+    auto powerState = entity.find("PowerState");
+    if (powerState == entity.end())
+    {
+        return false;
+    }
+
+    const auto* ptr = powerState->get_ptr<const std::string*>();
+    if (ptr == nullptr)
+    {
+        return false;
+    }
+
+    return *ptr == "On" || *ptr == "BiosPost";
+}
+
+static void pruneDevice(const nlohmann::json& systemConfiguration,
+                        const bool powerOff, const bool scannedPowerOff,
+                        const std::string& name, const nlohmann::json& device)
+{
+    if (systemConfiguration.contains(name))
+    {
+        return;
+    }
+
+    if (deviceRequiresPowerOn(device) && (powerOff || scannedPowerOff))
+    {
+        return;
+    }
+
+    logDeviceRemoved(device);
+}
+
+void startRemovedTimer(boost::asio::steady_timer& timer,
+                       nlohmann::json& systemConfiguration)
+{
+    static bool scannedPowerOff = false;
+    static bool scannedPowerOn = false;
+
+    if (systemConfiguration.empty() || lastJson.empty())
+    {
+        return; // not ready yet
+    }
+    if (scannedPowerOn)
+    {
+        return;
+    }
+
+    if (!isPowerOn() && scannedPowerOff)
+    {
+        return;
+    }
+
+    timer.expires_after(std::chrono::seconds(10));
+    timer.async_wait(
+        [&systemConfiguration](const boost::system::error_code& ec) {
+            if (ec == boost::asio::error::operation_aborted)
+            {
+                return;
+            }
+
+            bool powerOff = !isPowerOn();
+            for (const auto& [name, device] : lastJson.items())
+            {
+                pruneDevice(systemConfiguration, powerOff, scannedPowerOff,
+                            name, device);
+            }
+
+            scannedPowerOff = true;
+            if (!powerOff)
+            {
+                scannedPowerOn = true;
+            }
+        });
+}
+
+static void pruneConfiguration(nlohmann::json& systemConfiguration,
+                               sdbusplus::asio::object_server& objServer,
+                               bool powerOff, const std::string& name,
+                               const nlohmann::json& device)
+{
+    if (powerOff && deviceRequiresPowerOn(device))
+    {
+        // power not on yet, don't know if it's there or not
+        return;
+    }
+
+    auto& ifaces = dbus_interface::getDeviceInterfaces(device);
+    for (auto& iface : ifaces)
+    {
+        auto sharedPtr = iface.lock();
+        if (!!sharedPtr)
+        {
+            objServer.remove_interface(sharedPtr);
+        }
+    }
+
+    ifaces.clear();
+    systemConfiguration.erase(name);
+    topology.remove(device["Name"].get<std::string>());
+    logDeviceRemoved(device);
+}
+
+static void publishNewConfiguration(
+    const size_t& instance, const size_t count,
+    boost::asio::steady_timer& timer, nlohmann::json& systemConfiguration,
+    // Gerrit discussion:
+    // https://gerrit.openbmc-project.xyz/c/openbmc/entity-manager/+/52316/6
+    //
+    // Discord discussion:
+    // https://discord.com/channels/775381525260664832/867820390406422538/958048437729910854
+    //
+    // NOLINTNEXTLINE(performance-unnecessary-value-param)
+    const nlohmann::json newConfiguration,
+    sdbusplus::asio::object_server& objServer)
+{
+    loadOverlays(newConfiguration);
+
+    boost::asio::post(io, [systemConfiguration]() {
+        if (!configuration::writeJsonFiles(systemConfiguration))
+        {
+            std::cerr << "Error writing json files\n";
+        }
+    });
+
+    boost::asio::post(io, [&instance, count, &timer, newConfiguration,
+                           &systemConfiguration, &objServer]() {
+        postToDbus(newConfiguration, systemConfiguration, objServer);
+        if (count == instance)
+        {
+            startRemovedTimer(timer, systemConfiguration);
+        }
+    });
+}
+
+// main properties changed entry
+void propertiesChangedCallback(nlohmann::json& systemConfiguration,
+                               sdbusplus::asio::object_server& objServer)
+{
+    static bool inProgress = false;
+    static boost::asio::steady_timer timer(io);
+    static size_t instance = 0;
+    instance++;
+    size_t count = instance;
+
+    timer.expires_after(std::chrono::milliseconds(500));
+
+    // setup an async wait as we normally get flooded with new requests
+    timer.async_wait([&systemConfiguration, &objServer,
+                      count](const boost::system::error_code& ec) {
+        if (ec == boost::asio::error::operation_aborted)
+        {
+            // we were cancelled
+            return;
+        }
+        if (ec)
+        {
+            std::cerr << "async wait error " << ec << "\n";
+            return;
+        }
+
+        if (inProgress)
+        {
+            propertiesChangedCallback(systemConfiguration, objServer);
+            return;
+        }
+        inProgress = true;
+
+        nlohmann::json oldConfiguration = systemConfiguration;
+        auto missingConfigurations = std::make_shared<nlohmann::json>();
+        *missingConfigurations = systemConfiguration;
+
+        std::list<nlohmann::json> configurations;
+        if (!configuration::loadConfigurations(configurations))
+        {
+            std::cerr << "Could not load configurations\n";
+            inProgress = false;
+            return;
+        }
+
+        auto perfScan = std::make_shared<scan::PerformScan>(
+            systemConfiguration, *missingConfigurations, configurations,
+            objServer,
+            [&systemConfiguration, &objServer, count, oldConfiguration,
+             missingConfigurations]() {
+                // this is something that since ac has been applied to the bmc
+                // we saw, and we no longer see it
+                bool powerOff = !isPowerOn();
+                for (const auto& [name, device] :
+                     missingConfigurations->items())
+                {
+                    pruneConfiguration(systemConfiguration, objServer, powerOff,
+                                       name, device);
+                }
+
+                nlohmann::json newConfiguration = systemConfiguration;
+
+                configuration::deriveNewConfiguration(oldConfiguration,
+                                                      newConfiguration);
+
+                for (const auto& [_, device] : newConfiguration.items())
+                {
+                    logDeviceAdded(device);
+                }
+
+                inProgress = false;
+
+                boost::asio::post(
+                    io, std::bind_front(
+                            publishNewConfiguration, std::ref(instance), count,
+                            std::ref(timer), std::ref(systemConfiguration),
+                            newConfiguration, std::ref(objServer)));
+            });
+        perfScan->run();
+    });
+}
+
+// Check if InterfacesAdded payload contains an iface that needs probing.
+static bool iaContainsProbeInterface(
+    sdbusplus::message_t& msg, const std::set<std::string>& probeInterfaces)
+{
+    sdbusplus::message::object_path path;
+    DBusObject interfaces;
+    std::set<std::string> interfaceSet;
+    std::set<std::string> intersect;
+
+    msg.read(path, interfaces);
+
+    std::for_each(interfaces.begin(), interfaces.end(),
+                  [&interfaceSet](const auto& iface) {
+                      interfaceSet.insert(iface.first);
+                  });
+
+    std::set_intersection(interfaceSet.begin(), interfaceSet.end(),
+                          probeInterfaces.begin(), probeInterfaces.end(),
+                          std::inserter(intersect, intersect.end()));
+    return !intersect.empty();
+}
+
+// Check if InterfacesRemoved payload contains an iface that needs probing.
+static bool irContainsProbeInterface(
+    sdbusplus::message_t& msg, const std::set<std::string>& probeInterfaces)
+{
+    sdbusplus::message::object_path path;
+    std::set<std::string> interfaces;
+    std::set<std::string> intersect;
+
+    msg.read(path, interfaces);
+
+    std::set_intersection(interfaces.begin(), interfaces.end(),
+                          probeInterfaces.begin(), probeInterfaces.end(),
+                          std::inserter(intersect, intersect.end()));
+    return !intersect.empty();
+}
+
+int main()
+{
+    // setup connection to dbus
+    systemBus = std::make_shared<sdbusplus::asio::connection>(io);
+    systemBus->request_name("xyz.openbmc_project.EntityManager");
+
+    // The EntityManager object itself doesn't expose any properties.
+    // No need to set up ObjectManager for the |EntityManager| object.
+    sdbusplus::asio::object_server objServer(systemBus, /*skipManager=*/true);
+
+    // All other objects that EntityManager currently support are under the
+    // inventory subtree.
+    // See the discussion at
+    // https://discord.com/channels/775381525260664832/1018929092009144380
+    objServer.add_manager("/xyz/openbmc_project/inventory");
+
+    std::shared_ptr<sdbusplus::asio::dbus_interface> entityIface =
+        objServer.add_interface("/xyz/openbmc_project/EntityManager",
+                                "xyz.openbmc_project.EntityManager");
+
+    // to keep reference to the match / filter objects so they don't get
+    // destroyed
+
+    nlohmann::json systemConfiguration = nlohmann::json::object();
+
+    std::set<std::string> probeInterfaces = configuration::getProbeInterfaces();
+
+    // We need a poke from DBus for static providers that create all their
+    // objects prior to claiming a well-known name, and thus don't emit any
+    // org.freedesktop.DBus.Properties signals.  Similarly if a process exits
+    // for any reason, expected or otherwise, we'll need a poke to remove
+    // entities from DBus.
+    sdbusplus::bus::match_t nameOwnerChangedMatch(
+        static_cast<sdbusplus::bus_t&>(*systemBus),
+        sdbusplus::bus::match::rules::nameOwnerChanged(),
+        [&](sdbusplus::message_t& m) {
+            auto [name, oldOwner,
+                  newOwner] = m.unpack<std::string, std::string, std::string>();
+
+            if (name.starts_with(':'))
+            {
+                // We should do nothing with unique-name connections.
+                return;
+            }
+
+            propertiesChangedCallback(systemConfiguration, objServer);
+        });
+    // We also need a poke from DBus when new interfaces are created or
+    // destroyed.
+    sdbusplus::bus::match_t interfacesAddedMatch(
+        static_cast<sdbusplus::bus_t&>(*systemBus),
+        sdbusplus::bus::match::rules::interfacesAdded(),
+        [&](sdbusplus::message_t& msg) {
+            if (iaContainsProbeInterface(msg, probeInterfaces))
+            {
+                propertiesChangedCallback(systemConfiguration, objServer);
+            }
+        });
+    sdbusplus::bus::match_t interfacesRemovedMatch(
+        static_cast<sdbusplus::bus_t&>(*systemBus),
+        sdbusplus::bus::match::rules::interfacesRemoved(),
+        [&](sdbusplus::message_t& msg) {
+            if (irContainsProbeInterface(msg, probeInterfaces))
+            {
+                propertiesChangedCallback(systemConfiguration, objServer);
+            }
+        });
+
+    boost::asio::post(io, [&]() {
+        propertiesChangedCallback(systemConfiguration, objServer);
+    });
+
+    entityIface->register_method("ReScan", [&]() {
+        propertiesChangedCallback(systemConfiguration, objServer);
+    });
+    dbus_interface::tryIfaceInitialize(entityIface);
+
+    if (fwVersionIsSame())
+    {
+        if (std::filesystem::is_regular_file(
+                configuration::currentConfiguration))
+        {
+            // this file could just be deleted, but it's nice for debug
+            std::filesystem::create_directory(tempConfigDir);
+            std::filesystem::remove(lastConfiguration);
+            std::filesystem::copy(configuration::currentConfiguration,
+                                  lastConfiguration);
+            std::filesystem::remove(configuration::currentConfiguration);
+
+            std::ifstream jsonStream(lastConfiguration);
+            if (jsonStream.good())
+            {
+                auto data = nlohmann::json::parse(jsonStream, nullptr, false);
+                if (data.is_discarded())
+                {
+                    std::cerr
+                        << "syntax error in " << lastConfiguration << "\n";
+                }
+                else
+                {
+                    lastJson = std::move(data);
+                }
+            }
+            else
+            {
+                std::cerr << "unable to open " << lastConfiguration << "\n";
+            }
+        }
+    }
+    else
+    {
+        // not an error, just logging at this level to make it in the journal
+        std::cerr << "Clearing previous configuration\n";
+        std::filesystem::remove(configuration::currentConfiguration);
+    }
+
+    // some boards only show up after power is on, we want to not say they are
+    // removed until the same state happens
+    setupPowerMatch(systemBus);
+
+    io.run();
+
+    return 0;
+}
diff --git a/src/entity_manager/entity_manager.hpp b/src/entity_manager/entity_manager.hpp
new file mode 100644
index 0000000..ccd106e
--- /dev/null
+++ b/src/entity_manager/entity_manager.hpp
@@ -0,0 +1,136 @@
+/*
+// 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 entity_manager.hpp
+
+#pragma once
+
+#include "../utils.hpp"
+
+#include <systemd/sd-journal.h>
+
+#include <boost/container/flat_map.hpp>
+#include <nlohmann/json.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+
+#include <string>
+
+inline void logDeviceAdded(const nlohmann::json& record)
+{
+    if (!deviceHasLogging(record))
+    {
+        return;
+    }
+    auto findType = record.find("Type");
+    auto findAsset =
+        record.find("xyz.openbmc_project.Inventory.Decorator.Asset");
+
+    std::string model = "Unknown";
+    std::string type = "Unknown";
+    std::string sn = "Unknown";
+    std::string name = "Unknown";
+
+    if (findType != record.end())
+    {
+        type = findType->get<std::string>();
+    }
+    if (findAsset != record.end())
+    {
+        auto findModel = findAsset->find("Model");
+        auto findSn = findAsset->find("SerialNumber");
+        if (findModel != findAsset->end())
+        {
+            model = findModel->get<std::string>();
+        }
+        if (findSn != findAsset->end())
+        {
+            const std::string* getSn = findSn->get_ptr<const std::string*>();
+            if (getSn != nullptr)
+            {
+                sn = *getSn;
+            }
+            else
+            {
+                sn = findSn->dump();
+            }
+        }
+    }
+
+    auto findName = record.find("Name");
+    if (findName != record.end())
+    {
+        name = findName->get<std::string>();
+    }
+
+    sd_journal_send("MESSAGE=Inventory Added: %s", name.c_str(), "PRIORITY=%i",
+                    LOG_INFO, "REDFISH_MESSAGE_ID=%s",
+                    "OpenBMC.0.1.InventoryAdded",
+                    "REDFISH_MESSAGE_ARGS=%s,%s,%s", model.c_str(),
+                    type.c_str(), sn.c_str(), "NAME=%s", name.c_str(), NULL);
+}
+
+inline void logDeviceRemoved(const nlohmann::json& record)
+{
+    if (!deviceHasLogging(record))
+    {
+        return;
+    }
+    auto findType = record.find("Type");
+    auto findAsset =
+        record.find("xyz.openbmc_project.Inventory.Decorator.Asset");
+
+    std::string model = "Unknown";
+    std::string type = "Unknown";
+    std::string sn = "Unknown";
+    std::string name = "Unknown";
+
+    if (findType != record.end())
+    {
+        type = findType->get<std::string>();
+    }
+    if (findAsset != record.end())
+    {
+        auto findModel = findAsset->find("Model");
+        auto findSn = findAsset->find("SerialNumber");
+        if (findModel != findAsset->end())
+        {
+            model = findModel->get<std::string>();
+        }
+        if (findSn != findAsset->end())
+        {
+            const std::string* getSn = findSn->get_ptr<const std::string*>();
+            if (getSn != nullptr)
+            {
+                sn = *getSn;
+            }
+            else
+            {
+                sn = findSn->dump();
+            }
+        }
+    }
+
+    auto findName = record.find("Name");
+    if (findName != record.end())
+    {
+        name = findName->get<std::string>();
+    }
+
+    sd_journal_send("MESSAGE=Inventory Removed: %s", name.c_str(),
+                    "PRIORITY=%i", LOG_INFO, "REDFISH_MESSAGE_ID=%s",
+                    "OpenBMC.0.1.InventoryRemoved",
+                    "REDFISH_MESSAGE_ARGS=%s,%s,%s", model.c_str(),
+                    type.c_str(), sn.c_str(), "NAME=%s", name.c_str(), NULL);
+}
diff --git a/src/entity_manager/meson.build b/src/entity_manager/meson.build
new file mode 100644
index 0000000..005a0d0
--- /dev/null
+++ b/src/entity_manager/meson.build
@@ -0,0 +1,23 @@
+executable(
+    'entity-manager',
+    'entity_manager.cpp',
+    'configuration.cpp',
+    '../expression.cpp',
+    'dbus_interface.cpp',
+    'perform_scan.cpp',
+    'perform_probe.cpp',
+    'overlay.cpp',
+    'topology.cpp',
+    '../utils.cpp',
+    cpp_args: cpp_args + ['-DBOOST_ASIO_DISABLE_THREADS'],
+    dependencies: [
+        boost,
+        nlohmann_json_dep,
+        phosphor_logging_dep,
+        sdbusplus,
+        valijson,
+    ],
+    install: true,
+    install_dir: installdir,
+)
+
diff --git a/src/entity_manager/overlay.cpp b/src/entity_manager/overlay.cpp
new file mode 100644
index 0000000..8b52fb9
--- /dev/null
+++ b/src/entity_manager/overlay.cpp
@@ -0,0 +1,323 @@
+/*
+// 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 overlay.cpp
+
+#include "overlay.hpp"
+
+#include "../utils.hpp"
+#include "devices.hpp"
+
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/steady_timer.hpp>
+#include <boost/container/flat_map.hpp>
+#include <boost/container/flat_set.hpp>
+#include <boost/process/child.hpp>
+#include <nlohmann/json.hpp>
+#include <phosphor-logging/lg2.hpp>
+
+#include <filesystem>
+#include <iomanip>
+#include <iostream>
+#include <regex>
+#include <string>
+
+constexpr const char* outputDir = "/tmp/overlays";
+constexpr const char* templateChar = "$";
+constexpr const char* i2CDevsDir = "/sys/bus/i2c/devices";
+constexpr const char* muxSymlinkDir = "/dev/i2c-mux";
+
+const std::regex illegalNameRegex("[^A-Za-z0-9_]");
+
+// helper function to make json types into string
+std::string jsonToString(const nlohmann::json& in)
+{
+    if (in.type() == nlohmann::json::value_t::string)
+    {
+        return in.get<std::string>();
+    }
+    if (in.type() == nlohmann::json::value_t::array)
+    {
+        // remove brackets and comma from array
+        std::string array = in.dump();
+        array = array.substr(1, array.size() - 2);
+        boost::replace_all(array, ",", " ");
+        return array;
+    }
+    return in.dump();
+}
+
+static std::string deviceDirName(uint64_t bus, uint64_t address)
+{
+    std::ostringstream name;
+    name << bus << "-" << std::hex << std::setw(4) << std::setfill('0')
+         << address;
+    return name.str();
+}
+
+void linkMux(const std::string& muxName, uint64_t busIndex, uint64_t address,
+             const std::vector<std::string>& channelNames)
+{
+    std::error_code ec;
+    std::filesystem::path muxSymlinkDirPath(muxSymlinkDir);
+    std::filesystem::create_directory(muxSymlinkDirPath, ec);
+    // ignore error codes here if the directory already exists
+    ec.clear();
+    std::filesystem::path linkDir = muxSymlinkDirPath / muxName;
+    std::filesystem::create_directory(linkDir, ec);
+
+    std::filesystem::path devDir(i2CDevsDir);
+    devDir /= deviceDirName(busIndex, address);
+
+    for (std::size_t channelIndex = 0; channelIndex < channelNames.size();
+         channelIndex++)
+    {
+        const std::string& channelName = channelNames[channelIndex];
+        if (channelName.empty())
+        {
+            continue;
+        }
+
+        std::filesystem::path channelPath =
+            devDir / ("channel-" + std::to_string(channelIndex));
+        if (!is_symlink(channelPath))
+        {
+            std::cerr << channelPath << " for mux channel " << channelName
+                      << " doesn't exist!\n";
+            continue;
+        }
+        std::filesystem::path bus = std::filesystem::read_symlink(channelPath);
+
+        std::filesystem::path fp("/dev" / bus.filename());
+        std::filesystem::path link(linkDir / channelName);
+
+        std::filesystem::create_symlink(fp, link, ec);
+        if (ec)
+        {
+            std::cerr << "Failure creating symlink for " << fp << " to " << link
+                      << "\n";
+        }
+    }
+}
+
+static int deleteDevice(const std::string& busPath, uint64_t address,
+                        const std::string& destructor)
+{
+    std::filesystem::path deviceDestructor(busPath);
+    deviceDestructor /= destructor;
+    std::ofstream deviceFile(deviceDestructor);
+    if (!deviceFile.good())
+    {
+        std::cerr << "Error writing " << deviceDestructor << "\n";
+        return -1;
+    }
+    deviceFile << std::to_string(address);
+    deviceFile.close();
+    return 0;
+}
+
+static int createDevice(const std::string& busPath,
+                        const std::string& parameters,
+                        const std::string& constructor)
+{
+    std::filesystem::path deviceConstructor(busPath);
+    deviceConstructor /= constructor;
+    std::ofstream deviceFile(deviceConstructor);
+    if (!deviceFile.good())
+    {
+        std::cerr << "Error writing " << deviceConstructor << "\n";
+        return -1;
+    }
+    deviceFile << parameters;
+    deviceFile.close();
+
+    return 0;
+}
+
+static bool deviceIsCreated(const std::string& busPath, uint64_t bus,
+                            uint64_t address,
+                            const devices::createsHWMon hasHWMonDir)
+{
+    std::filesystem::path dirPath = busPath;
+    dirPath /= deviceDirName(bus, address);
+    if (hasHWMonDir == devices::createsHWMon::hasHWMonDir)
+    {
+        dirPath /= "hwmon";
+    }
+
+    std::error_code ec;
+    // Ignore errors; anything but a clean 'true' is just fine as 'false'
+    return std::filesystem::exists(dirPath, ec);
+}
+
+static int buildDevice(
+    const std::string& name, const std::string& busPath,
+    const std::string& parameters, uint64_t bus, uint64_t address,
+    const std::string& constructor, const std::string& destructor,
+    const devices::createsHWMon hasHWMonDir,
+    std::vector<std::string> channelNames, const size_t retries = 5)
+{
+    if (retries == 0U)
+    {
+        return -1;
+    }
+
+    // If it's already instantiated, we don't need to create it again.
+    if (!deviceIsCreated(busPath, bus, address, hasHWMonDir))
+    {
+        // Try to create the device
+        createDevice(busPath, parameters, constructor);
+
+        // If it didn't work, delete it and try again in 500ms
+        if (!deviceIsCreated(busPath, bus, address, hasHWMonDir))
+        {
+            deleteDevice(busPath, address, destructor);
+
+            std::shared_ptr<boost::asio::steady_timer> createTimer =
+                std::make_shared<boost::asio::steady_timer>(io);
+            createTimer->expires_after(std::chrono::milliseconds(500));
+            createTimer->async_wait(
+                [createTimer, name, busPath, parameters, bus, address,
+                 constructor, destructor, hasHWMonDir,
+                 channelNames(std::move(channelNames)),
+                 retries](const boost::system::error_code& ec) mutable {
+                    if (ec)
+                    {
+                        std::cerr << "Timer error: " << ec << "\n";
+                        return -2;
+                    }
+                    return buildDevice(name, busPath, parameters, bus, address,
+                                       constructor, destructor, hasHWMonDir,
+                                       std::move(channelNames), retries - 1);
+                });
+            return -1;
+        }
+    }
+
+    // Link the mux channels if needed once the device is created.
+    if (!channelNames.empty())
+    {
+        linkMux(name, bus, address, channelNames);
+    }
+
+    return 0;
+}
+
+void exportDevice(const std::string& type,
+                  const devices::ExportTemplate& exportTemplate,
+                  const nlohmann::json& configuration)
+{
+    std::string parameters = exportTemplate.parameters;
+    std::string busPath = exportTemplate.busPath;
+    std::string constructor = exportTemplate.add;
+    std::string destructor = exportTemplate.remove;
+    devices::createsHWMon hasHWMonDir = exportTemplate.hasHWMonDir;
+    std::string name = "unknown";
+    std::optional<uint64_t> bus;
+    std::optional<uint64_t> address;
+    std::vector<std::string> channels;
+
+    for (auto keyPair = configuration.begin(); keyPair != configuration.end();
+         keyPair++)
+    {
+        std::string subsituteString;
+
+        if (keyPair.key() == "Name" &&
+            keyPair.value().type() == nlohmann::json::value_t::string)
+        {
+            subsituteString = std::regex_replace(
+                keyPair.value().get<std::string>(), illegalNameRegex, "_");
+            name = subsituteString;
+        }
+        else
+        {
+            subsituteString = jsonToString(keyPair.value());
+        }
+
+        if (keyPair.key() == "Bus")
+        {
+            bus = keyPair.value().get<uint64_t>();
+        }
+        else if (keyPair.key() == "Address")
+        {
+            address = keyPair.value().get<uint64_t>();
+        }
+        else if (keyPair.key() == "ChannelNames" && type.ends_with("Mux"))
+        {
+            channels = keyPair.value().get<std::vector<std::string>>();
+        }
+        boost::replace_all(parameters, templateChar + keyPair.key(),
+                           subsituteString);
+        boost::replace_all(busPath, templateChar + keyPair.key(),
+                           subsituteString);
+    }
+
+    if (!bus || !address)
+    {
+        createDevice(busPath, parameters, constructor);
+        return;
+    }
+
+    buildDevice(name, busPath, parameters, *bus, *address, constructor,
+                destructor, hasHWMonDir, std::move(channels));
+}
+
+bool loadOverlays(const nlohmann::json& systemConfiguration)
+{
+    std::filesystem::create_directory(outputDir);
+    for (auto entity = systemConfiguration.begin();
+         entity != systemConfiguration.end(); entity++)
+    {
+        auto findExposes = entity.value().find("Exposes");
+        if (findExposes == entity.value().end() ||
+            findExposes->type() != nlohmann::json::value_t::array)
+        {
+            continue;
+        }
+
+        for (const auto& configuration : *findExposes)
+        {
+            auto findStatus = configuration.find("Status");
+            // status missing is assumed to be 'okay'
+            if (findStatus != configuration.end() && *findStatus == "disabled")
+            {
+                continue;
+            }
+            auto findType = configuration.find("Type");
+            if (findType == configuration.end() ||
+                findType->type() != nlohmann::json::value_t::string)
+            {
+                continue;
+            }
+            std::string type = findType.value().get<std::string>();
+            auto device = devices::exportTemplates.find(type.c_str());
+            if (device != devices::exportTemplates.end())
+            {
+                exportDevice(type, device->second, configuration);
+                continue;
+            }
+
+            // Because many devices are intentionally not exportable,
+            // this error message is not printed in all situations.
+            // If wondering why your device not appearing, add your type to
+            // the exportTemplates array in the devices.hpp file.
+            lg2::debug("Device type {TYPE} not found in export map allowlist",
+                       "TYPE", type);
+        }
+    }
+
+    return true;
+}
diff --git a/src/entity_manager/overlay.hpp b/src/entity_manager/overlay.hpp
new file mode 100644
index 0000000..3bc6eb7
--- /dev/null
+++ b/src/entity_manager/overlay.hpp
@@ -0,0 +1,22 @@
+/*
+// 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 overlay.hpp
+
+#pragma once
+#include <nlohmann/json.hpp>
+
+void unloadAllOverlays();
+bool loadOverlays(const nlohmann::json& systemConfiguration);
diff --git a/src/entity_manager/perform_probe.cpp b/src/entity_manager/perform_probe.cpp
new file mode 100644
index 0000000..d7dcd8a
--- /dev/null
+++ b/src/entity_manager/perform_probe.cpp
@@ -0,0 +1,258 @@
+/*
+// 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 perform_probe.cpp
+#include "perform_probe.hpp"
+
+#include "entity_manager.hpp"
+#include "perform_scan.hpp"
+
+#include <boost/algorithm/string/replace.hpp>
+#include <phosphor-logging/lg2.hpp>
+
+#include <regex>
+#include <utility>
+
+// 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& interfaceName,
+               const std::map<std::string, nlohmann::json>& matches,
+               scan::FoundDevices& devices,
+               const std::shared_ptr<scan::PerformScan>& scan, bool& foundProbe)
+{
+    bool foundMatch = false;
+    foundProbe = false;
+
+    for (const auto& [path, interfaces] : scan->dbusProbeObjects)
+    {
+        auto it = interfaces.find(interfaceName);
+        if (it == interfaces.end())
+        {
+            continue;
+        }
+
+        foundProbe = true;
+
+        bool deviceMatches = true;
+        const DBusInterface& interface = it->second;
+
+        for (const auto& [matchProp, matchJSON] : matches)
+        {
+            auto deviceValue = interface.find(matchProp);
+            if (deviceValue != interface.end())
+            {
+                deviceMatches = deviceMatches &&
+                                matchProbe(matchJSON, deviceValue->second);
+            }
+            else
+            {
+                // Move on to the next DBus path
+                deviceMatches = false;
+                break;
+            }
+        }
+        if (deviceMatches)
+        {
+            lg2::debug("Found probe match on {PATH} {IFACE}", "PATH", path,
+                       "IFACE", interfaceName);
+            devices.emplace_back(interface, path);
+            foundMatch = true;
+        }
+    }
+    return foundMatch;
+}
+
+// default probe entry point, iterates a list looking for specific types to
+// call specific probe functions
+bool doProbe(const std::vector<std::string>& probeCommand,
+             const std::shared_ptr<scan::PerformScan>& scan,
+             scan::FoundDevices& foundDevs)
+{
+    const static std::regex command(R"(\((.*)\))");
+    std::smatch match;
+    bool ret = false;
+    bool matchOne = false;
+    bool cur = true;
+    probe::probe_type_codes lastCommand = probe::probe_type_codes::FALSE_T;
+    bool first = true;
+
+    for (const auto& probe : probeCommand)
+    {
+        probe::FoundProbeTypeT probeType = probe::findProbeType(probe);
+        if (probeType)
+        {
+            switch ((*probeType)->second)
+            {
+                case probe::probe_type_codes::FALSE_T:
+                {
+                    cur = false;
+                    break;
+                }
+                case probe::probe_type_codes::TRUE_T:
+                {
+                    cur = true;
+                    break;
+                }
+                case probe::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::probe_type_codes::AND:
+                  break;
+                case probe::probe_type_codes::OR:
+                  break;
+                  // these are no-ops until the last command switch
+                  */
+                case probe::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, true);
+            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;
+            }
+            bool foundProbe = !!probeType;
+            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::probe_type_codes::AND)
+        {
+            ret = cur && ret;
+        }
+        else if (lastCommand == probe::probe_type_codes::OR)
+        {
+            ret = cur || ret;
+        }
+
+        if (first)
+        {
+            ret = cur;
+            first = false;
+        }
+        lastCommand = probeType ? (*probeType)->second
+                                : probe::probe_type_codes::FALSE_T;
+    }
+
+    // probe passed, but empty device
+    if (ret && foundDevs.empty())
+    {
+        foundDevs.emplace_back(
+            boost::container::flat_map<std::string, DBusValueVariant>{},
+            std::string{});
+    }
+    if (matchOne && ret)
+    {
+        // match the last one
+        auto last = foundDevs.back();
+        foundDevs.clear();
+
+        foundDevs.emplace_back(std::move(last));
+    }
+    return ret;
+}
+
+namespace probe
+{
+
+PerformProbe::PerformProbe(nlohmann::json& recordRef,
+                           const std::vector<std::string>& probeCommand,
+                           std::string probeName,
+                           std::shared_ptr<scan::PerformScan>& scanPtr) :
+    recordRef(recordRef), _probeCommand(probeCommand),
+    probeName(std::move(probeName)), scan(scanPtr)
+{}
+
+PerformProbe::~PerformProbe()
+{
+    scan::FoundDevices foundDevs;
+    if (doProbe(_probeCommand, scan, foundDevs))
+    {
+        scan->updateSystemConfiguration(recordRef, probeName, foundDevs);
+    }
+}
+
+FoundProbeTypeT findProbeType(const std::string& probe)
+{
+    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}}};
+
+    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)
+        {
+            return probeType;
+        }
+    }
+
+    return std::nullopt;
+}
+
+} // namespace probe
diff --git a/src/entity_manager/perform_probe.hpp b/src/entity_manager/perform_probe.hpp
new file mode 100644
index 0000000..f979c52
--- /dev/null
+++ b/src/entity_manager/perform_probe.hpp
@@ -0,0 +1,52 @@
+#pragma once
+
+#include "perform_scan.hpp"
+
+#include <boost/container/flat_map.hpp>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace probe
+{
+struct CmpStr
+{
+    bool operator()(const char* a, const char* b) const
+    {
+        return std::strcmp(a, b) < 0;
+    }
+};
+
+// underscore T for collison with dbus c api
+enum class probe_type_codes
+{
+    FALSE_T,
+    TRUE_T,
+    AND,
+    OR,
+    FOUND,
+    MATCH_ONE
+};
+
+using FoundProbeTypeT = std::optional<boost::container::flat_map<
+    const char*, probe_type_codes, CmpStr>::const_iterator>;
+
+FoundProbeTypeT findProbeType(const std::string& probe);
+
+// this class finds the needed dbus fields and on destruction runs the probe
+struct PerformProbe : std::enable_shared_from_this<PerformProbe>
+{
+    PerformProbe(nlohmann::json& recordRef,
+                 const std::vector<std::string>& probeCommand,
+                 std::string probeName,
+                 std::shared_ptr<scan::PerformScan>& scanPtr);
+    virtual ~PerformProbe();
+
+    nlohmann::json& recordRef;
+    std::vector<std::string> _probeCommand;
+    std::string probeName;
+    std::shared_ptr<scan::PerformScan> scan;
+};
+
+} // namespace probe
diff --git a/src/entity_manager/perform_scan.cpp b/src/entity_manager/perform_scan.cpp
new file mode 100644
index 0000000..d05312d
--- /dev/null
+++ b/src/entity_manager/perform_scan.cpp
@@ -0,0 +1,664 @@
+/*
+// 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 perform_scan.cpp
+#include "perform_scan.hpp"
+
+#include "entity_manager.hpp"
+#include "perform_probe.hpp"
+
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/asio/steady_timer.hpp>
+#include <boost/container/flat_map.hpp>
+#include <boost/container/flat_set.hpp>
+#include <phosphor-logging/lg2.hpp>
+
+#include <charconv>
+
+/* Hacks from splitting entity_manager.cpp */
+// NOLINTBEGIN(cppcoreguidelines-avoid-non-const-global-variables)
+extern std::shared_ptr<sdbusplus::asio::connection> systemBus;
+extern nlohmann::json lastJson;
+extern void propertiesChangedCallback(
+    nlohmann::json& systemConfiguration,
+    sdbusplus::asio::object_server& objServer);
+// NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables)
+
+using GetSubTreeType = std::vector<
+    std::pair<std::string,
+              std::vector<std::pair<std::string, std::vector<std::string>>>>>;
+
+constexpr const int32_t maxMapperDepth = 0;
+
+struct DBusInterfaceInstance
+{
+    std::string busName;
+    std::string path;
+    std::string interface;
+};
+
+void getInterfaces(
+    const DBusInterfaceInstance& instance,
+    const std::vector<std::shared_ptr<probe::PerformProbe>>& probeVector,
+    const std::shared_ptr<scan::PerformScan>& scan, size_t retries = 5)
+{
+    if (retries == 0U)
+    {
+        std::cerr << "retries exhausted on " << instance.busName << " "
+                  << instance.path << " " << instance.interface << "\n";
+        return;
+    }
+
+    systemBus->async_method_call(
+        [instance, scan, probeVector,
+         retries](boost::system::error_code& errc, const DBusInterface& resp) {
+            if (errc)
+            {
+                std::cerr << "error calling getall on  " << instance.busName
+                          << " " << instance.path << " "
+                          << instance.interface << "\n";
+
+                auto timer = std::make_shared<boost::asio::steady_timer>(io);
+                timer->expires_after(std::chrono::seconds(2));
+
+                timer->async_wait([timer, instance, scan, probeVector,
+                                   retries](const boost::system::error_code&) {
+                    getInterfaces(instance, probeVector, scan, retries - 1);
+                });
+                return;
+            }
+
+            scan->dbusProbeObjects[instance.path][instance.interface] = resp;
+        },
+        instance.busName, instance.path, "org.freedesktop.DBus.Properties",
+        "GetAll", instance.interface);
+}
+
+static void registerCallback(nlohmann::json& systemConfiguration,
+                             sdbusplus::asio::object_server& objServer,
+                             const std::string& path)
+{
+    static boost::container::flat_map<std::string, sdbusplus::bus::match_t>
+        dbusMatches;
+
+    auto find = dbusMatches.find(path);
+    if (find != dbusMatches.end())
+    {
+        return;
+    }
+
+    std::function<void(sdbusplus::message_t & message)> eventHandler =
+        [&](sdbusplus::message_t&) {
+            propertiesChangedCallback(systemConfiguration, objServer);
+        };
+
+    sdbusplus::bus::match_t match(
+        static_cast<sdbusplus::bus_t&>(*systemBus),
+        "type='signal',member='PropertiesChanged',path='" + path + "'",
+        eventHandler);
+    dbusMatches.emplace(path, std::move(match));
+}
+
+static void processDbusObjects(
+    std::vector<std::shared_ptr<probe::PerformProbe>>& probeVector,
+    const std::shared_ptr<scan::PerformScan>& scan,
+    const GetSubTreeType& interfaceSubtree)
+{
+    for (const auto& [path, object] : interfaceSubtree)
+    {
+        // Get a PropertiesChanged callback for all interfaces on this path.
+        registerCallback(scan->_systemConfiguration, scan->objServer, path);
+
+        for (const auto& [busname, ifaces] : object)
+        {
+            for (const std::string& iface : ifaces)
+            {
+                // The 3 default org.freedeskstop interfaces (Peer,
+                // Introspectable, and Properties) are returned by
+                // the mapper but don't have properties, so don't bother
+                // with the GetAll call to save some cycles.
+                if (!boost::algorithm::starts_with(iface, "org.freedesktop"))
+                {
+                    getInterfaces({busname, path, iface}, probeVector, scan);
+                }
+            }
+        }
+    }
+}
+
+// Populates scan->dbusProbeObjects with all interfaces and properties
+// for the paths that own the interfaces passed in.
+void findDbusObjects(
+    std::vector<std::shared_ptr<probe::PerformProbe>>&& probeVector,
+    boost::container::flat_set<std::string>&& interfaces,
+    const std::shared_ptr<scan::PerformScan>& scan, size_t retries = 5)
+{
+    // Filter out interfaces already obtained.
+    for (const auto& [path, probeInterfaces] : scan->dbusProbeObjects)
+    {
+        for (const auto& [interface, _] : probeInterfaces)
+        {
+            interfaces.erase(interface);
+        }
+    }
+    if (interfaces.empty())
+    {
+        return;
+    }
+
+    // find all connections in the mapper that expose a specific type
+    systemBus->async_method_call(
+        [interfaces, probeVector{std::move(probeVector)}, scan,
+         retries](boost::system::error_code& ec,
+                  const GetSubTreeType& interfaceSubtree) mutable {
+            if (ec)
+            {
+                if (ec.value() == ENOENT)
+                {
+                    return; // wasn't found by mapper
+                }
+                std::cerr << "Error communicating to mapper.\n";
+
+                if (retries == 0U)
+                {
+                    // if we can't communicate to the mapper something is very
+                    // wrong
+                    std::exit(EXIT_FAILURE);
+                }
+
+                auto timer = std::make_shared<boost::asio::steady_timer>(io);
+                timer->expires_after(std::chrono::seconds(10));
+
+                timer->async_wait(
+                    [timer, interfaces{std::move(interfaces)}, scan,
+                     probeVector{std::move(probeVector)},
+                     retries](const boost::system::error_code&) mutable {
+                        findDbusObjects(std::move(probeVector),
+                                        std::move(interfaces), scan,
+                                        retries - 1);
+                    });
+                return;
+            }
+
+            processDbusObjects(probeVector, scan, interfaceSubtree);
+        },
+        "xyz.openbmc_project.ObjectMapper",
+        "/xyz/openbmc_project/object_mapper",
+        "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", maxMapperDepth,
+        interfaces);
+}
+
+static std::string getRecordName(const DBusInterface& probe,
+                                 const std::string& probeName)
+{
+    if (probe.empty())
+    {
+        return probeName;
+    }
+
+    // use an array so alphabetical order from the flat_map is maintained
+    auto device = nlohmann::json::array();
+    for (const auto& devPair : probe)
+    {
+        device.push_back(devPair.first);
+        std::visit([&device](auto&& v) { device.push_back(v); },
+                   devPair.second);
+    }
+
+    // hashes are hard to distinguish, use the non-hashed version if we want
+    // debug
+    // return probeName + device.dump();
+
+    return std::to_string(std::hash<std::string>{}(probeName + device.dump()));
+}
+
+scan::PerformScan::PerformScan(nlohmann::json& systemConfiguration,
+                               nlohmann::json& missingConfigurations,
+                               std::list<nlohmann::json>& configurations,
+                               sdbusplus::asio::object_server& objServerIn,
+                               std::function<void()>&& callback) :
+    _systemConfiguration(systemConfiguration),
+    _missingConfigurations(missingConfigurations),
+    _configurations(configurations), objServer(objServerIn),
+    _callback(std::move(callback))
+{}
+
+static void pruneRecordExposes(nlohmann::json& record)
+{
+    auto findExposes = record.find("Exposes");
+    if (findExposes == record.end())
+    {
+        return;
+    }
+
+    auto copy = nlohmann::json::array();
+    for (auto& expose : *findExposes)
+    {
+        if (!expose.is_null())
+        {
+            copy.emplace_back(expose);
+        }
+    }
+    *findExposes = copy;
+}
+
+static void recordDiscoveredIdentifiers(
+    std::set<nlohmann::json>& usedNames, std::list<size_t>& indexes,
+    const std::string& probeName, const nlohmann::json& record)
+{
+    size_t indexIdx = probeName.find('$');
+    if (indexIdx == std::string::npos)
+    {
+        return;
+    }
+
+    auto nameIt = record.find("Name");
+    if (nameIt == record.end())
+    {
+        std::cerr << "Last JSON Illegal\n";
+        return;
+    }
+
+    int index = 0;
+    auto str = nameIt->get<std::string>().substr(indexIdx);
+    // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
+    const char* endPtr = str.data() + str.size();
+    auto [p, ec] = std::from_chars(str.data(), endPtr, index);
+    if (ec != std::errc())
+    {
+        return; // non-numeric replacement
+    }
+
+    usedNames.insert(nameIt.value());
+
+    auto usedIt = std::find(indexes.begin(), indexes.end(), index);
+    if (usedIt != indexes.end())
+    {
+        indexes.erase(usedIt);
+    }
+}
+
+static bool extractExposeActionRecordNames(std::vector<std::string>& matches,
+                                           nlohmann::json::iterator& keyPair)
+{
+    if (keyPair.value().is_string())
+    {
+        matches.emplace_back(keyPair.value());
+        return true;
+    }
+
+    if (keyPair.value().is_array())
+    {
+        for (const auto& value : keyPair.value())
+        {
+            if (!value.is_string())
+            {
+                std::cerr << "Value is invalid type " << value << "\n";
+                break;
+            }
+            matches.emplace_back(value);
+        }
+
+        return true;
+    }
+
+    std::cerr << "Value is invalid type " << keyPair.key() << "\n";
+
+    return false;
+}
+
+static std::optional<std::vector<std::string>::iterator> findExposeActionRecord(
+    std::vector<std::string>& matches, const nlohmann::json& record)
+{
+    const auto& name = (record)["Name"].get_ref<const std::string&>();
+    auto compare = [&name](const std::string& s) { return s == name; };
+    auto matchIt = std::find_if(matches.begin(), matches.end(), compare);
+
+    if (matchIt == matches.end())
+    {
+        return std::nullopt;
+    }
+
+    return matchIt;
+}
+
+static void applyBindExposeAction(nlohmann::json& exposedObject,
+                                  nlohmann::json& expose,
+                                  const std::string& propertyName)
+{
+    if (boost::starts_with(propertyName, "Bind"))
+    {
+        std::string bind = propertyName.substr(sizeof("Bind") - 1);
+        exposedObject["Status"] = "okay";
+        expose[bind] = exposedObject;
+    }
+}
+
+static void applyDisableExposeAction(nlohmann::json& exposedObject,
+                                     const std::string& propertyName)
+{
+    if (propertyName == "DisableNode")
+    {
+        exposedObject["Status"] = "disabled";
+    }
+}
+
+static void applyConfigExposeActions(
+    std::vector<std::string>& matches, nlohmann::json& expose,
+    const std::string& propertyName, nlohmann::json& configExposes)
+{
+    for (auto& exposedObject : configExposes)
+    {
+        auto match = findExposeActionRecord(matches, exposedObject);
+        if (match)
+        {
+            matches.erase(*match);
+            applyBindExposeAction(exposedObject, expose, propertyName);
+            applyDisableExposeAction(exposedObject, propertyName);
+        }
+    }
+}
+
+static void applyExposeActions(
+    nlohmann::json& systemConfiguration, const std::string& recordName,
+    nlohmann::json& expose, nlohmann::json::iterator& keyPair)
+{
+    bool isBind = boost::starts_with(keyPair.key(), "Bind");
+    bool isDisable = keyPair.key() == "DisableNode";
+    bool isExposeAction = isBind || isDisable;
+
+    if (!isExposeAction)
+    {
+        return;
+    }
+
+    std::vector<std::string> matches;
+
+    if (!extractExposeActionRecordNames(matches, keyPair))
+    {
+        return;
+    }
+
+    for (const auto& [configId, config] : systemConfiguration.items())
+    {
+        // don't disable ourselves
+        if (isDisable && configId == recordName)
+        {
+            continue;
+        }
+
+        auto configListFind = config.find("Exposes");
+        if (configListFind == config.end())
+        {
+            continue;
+        }
+
+        if (!configListFind->is_array())
+        {
+            continue;
+        }
+
+        applyConfigExposeActions(matches, expose, keyPair.key(),
+                                 *configListFind);
+    }
+
+    if (!matches.empty())
+    {
+        std::cerr << "configuration file dependency error, could not find "
+                  << keyPair.key() << " " << keyPair.value() << "\n";
+    }
+}
+
+static std::string generateDeviceName(
+    const std::set<nlohmann::json>& usedNames, const DBusObject& dbusObject,
+    size_t foundDeviceIdx, const std::string& nameTemplate,
+    std::optional<std::string>& replaceStr)
+{
+    nlohmann::json copyForName = {{"Name", nameTemplate}};
+    nlohmann::json::iterator copyIt = copyForName.begin();
+    std::optional<std::string> replaceVal =
+        templateCharReplace(copyIt, dbusObject, foundDeviceIdx, replaceStr);
+
+    if (!replaceStr && replaceVal)
+    {
+        if (usedNames.find(copyIt.value()) != usedNames.end())
+        {
+            replaceStr = replaceVal;
+            copyForName = {{"Name", nameTemplate}};
+            copyIt = copyForName.begin();
+            templateCharReplace(copyIt, dbusObject, foundDeviceIdx, replaceStr);
+        }
+    }
+
+    if (replaceStr)
+    {
+        std::cerr << "Duplicates found, replacing " << *replaceStr
+                  << " with found device index.\n Consider "
+                     "fixing template to not have duplicates\n";
+    }
+
+    return copyIt.value();
+}
+
+void scan::PerformScan::updateSystemConfiguration(
+    const nlohmann::json& recordRef, const std::string& probeName,
+    FoundDevices& foundDevices)
+{
+    _passed = true;
+    passedProbes.push_back(probeName);
+
+    std::set<nlohmann::json> usedNames;
+    std::list<size_t> indexes(foundDevices.size());
+    std::iota(indexes.begin(), indexes.end(), 1);
+
+    // copy over persisted configurations and make sure we remove
+    // indexes that are already used
+    for (auto itr = foundDevices.begin(); itr != foundDevices.end();)
+    {
+        std::string recordName = getRecordName(itr->interface, probeName);
+
+        auto record = _systemConfiguration.find(recordName);
+        if (record == _systemConfiguration.end())
+        {
+            record = lastJson.find(recordName);
+            if (record == lastJson.end())
+            {
+                itr++;
+                continue;
+            }
+
+            pruneRecordExposes(*record);
+
+            _systemConfiguration[recordName] = *record;
+        }
+        _missingConfigurations.erase(recordName);
+
+        // We've processed the device, remove it and advance the
+        // iterator
+        itr = foundDevices.erase(itr);
+        recordDiscoveredIdentifiers(usedNames, indexes, probeName, *record);
+    }
+
+    std::optional<std::string> replaceStr;
+
+    DBusObject emptyObject;
+    DBusInterface emptyInterface;
+    emptyObject.emplace(std::string{}, emptyInterface);
+
+    for (const auto& [foundDevice, path] : foundDevices)
+    {
+        // Need all interfaces on this path so that template
+        // substitutions can be done with any of the contained
+        // properties.  If the probe that passed didn't use an
+        // interface, such as if it was just TRUE, then
+        // templateCharReplace will just get passed in an empty
+        // map.
+        auto objectIt = dbusProbeObjects.find(path);
+        const DBusObject& dbusObject = (objectIt == dbusProbeObjects.end())
+                                           ? emptyObject
+                                           : objectIt->second;
+
+        nlohmann::json record = recordRef;
+        std::string recordName = getRecordName(foundDevice, probeName);
+        size_t foundDeviceIdx = indexes.front();
+        indexes.pop_front();
+
+        // check name first so we have no duplicate names
+        auto getName = record.find("Name");
+        if (getName == record.end())
+        {
+            std::cerr << "Record Missing Name! " << record.dump();
+            continue; // this should be impossible at this level
+        }
+
+        std::string deviceName = generateDeviceName(
+            usedNames, dbusObject, foundDeviceIdx, getName.value(), replaceStr);
+        getName.value() = deviceName;
+        usedNames.insert(deviceName);
+
+        for (auto keyPair = record.begin(); keyPair != record.end(); keyPair++)
+        {
+            if (keyPair.key() != "Name")
+            {
+                templateCharReplace(keyPair, dbusObject, foundDeviceIdx,
+                                    replaceStr);
+            }
+        }
+
+        // insert into configuration temporarily to be able to
+        // reference ourselves
+
+        _systemConfiguration[recordName] = record;
+
+        auto findExpose = record.find("Exposes");
+        if (findExpose == record.end())
+        {
+            continue;
+        }
+
+        for (auto& expose : *findExpose)
+        {
+            for (auto keyPair = expose.begin(); keyPair != expose.end();
+                 keyPair++)
+            {
+                templateCharReplace(keyPair, dbusObject, foundDeviceIdx,
+                                    replaceStr);
+
+                applyExposeActions(_systemConfiguration, recordName, expose,
+                                   keyPair);
+            }
+        }
+
+        // overwrite ourselves with cleaned up version
+        _systemConfiguration[recordName] = record;
+        _missingConfigurations.erase(recordName);
+    }
+}
+
+void scan::PerformScan::run()
+{
+    boost::container::flat_set<std::string> dbusProbeInterfaces;
+    std::vector<std::shared_ptr<probe::PerformProbe>> dbusProbePointers;
+
+    for (auto it = _configurations.begin(); it != _configurations.end();)
+    {
+        // check for poorly formatted fields, probe must be an array
+        auto findProbe = it->find("Probe");
+        if (findProbe == it->end())
+        {
+            std::cerr << "configuration file missing probe:\n " << *it << "\n";
+            it = _configurations.erase(it);
+            continue;
+        }
+
+        auto findName = it->find("Name");
+        if (findName == it->end())
+        {
+            std::cerr << "configuration file missing name:\n " << *it << "\n";
+            it = _configurations.erase(it);
+            continue;
+        }
+        std::string probeName = *findName;
+
+        if (std::find(passedProbes.begin(), passedProbes.end(), probeName) !=
+            passedProbes.end())
+        {
+            it = _configurations.erase(it);
+            continue;
+        }
+
+        nlohmann::json& recordRef = *it;
+        nlohmann::json probeCommand;
+        if ((*findProbe).type() != nlohmann::json::value_t::array)
+        {
+            probeCommand = nlohmann::json::array();
+            probeCommand.push_back(*findProbe);
+        }
+        else
+        {
+            probeCommand = *findProbe;
+        }
+
+        // store reference to this to children to makes sure we don't get
+        // destroyed too early
+        auto thisRef = shared_from_this();
+        auto probePointer = std::make_shared<probe::PerformProbe>(
+            recordRef, probeCommand, probeName, thisRef);
+
+        // parse out dbus probes by discarding other probe types, store in a
+        // map
+        for (const nlohmann::json& probeJson : probeCommand)
+        {
+            const std::string* probe = probeJson.get_ptr<const std::string*>();
+            if (probe == nullptr)
+            {
+                std::cerr << "Probe statement wasn't a string, can't parse";
+                continue;
+            }
+            if (probe::findProbeType(*probe))
+            {
+                continue;
+            }
+            // syntax requires probe before first open brace
+            auto findStart = probe->find('(');
+            std::string interface = probe->substr(0, findStart);
+            dbusProbeInterfaces.emplace(interface);
+            dbusProbePointers.emplace_back(probePointer);
+        }
+        it++;
+    }
+
+    // probe vector stores a shared_ptr to each PerformProbe that cares
+    // about a dbus interface
+    findDbusObjects(std::move(dbusProbePointers),
+                    std::move(dbusProbeInterfaces), shared_from_this());
+}
+
+scan::PerformScan::~PerformScan()
+{
+    if (_passed)
+    {
+        auto nextScan = std::make_shared<PerformScan>(
+            _systemConfiguration, _missingConfigurations, _configurations,
+            objServer, std::move(_callback));
+        nextScan->passedProbes = std::move(passedProbes);
+        nextScan->dbusProbeObjects = std::move(dbusProbeObjects);
+        nextScan->run();
+    }
+    else
+    {
+        _callback();
+    }
+}
diff --git a/src/entity_manager/perform_scan.hpp b/src/entity_manager/perform_scan.hpp
new file mode 100644
index 0000000..ae57582
--- /dev/null
+++ b/src/entity_manager/perform_scan.hpp
@@ -0,0 +1,48 @@
+#pragma once
+
+#include "../utils.hpp"
+
+#include <systemd/sd-journal.h>
+
+#include <boost/container/flat_map.hpp>
+#include <nlohmann/json.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+
+#include <functional>
+#include <list>
+#include <vector>
+
+namespace scan
+{
+struct DBusDeviceDescriptor
+{
+    DBusInterface interface;
+    std::string path;
+};
+
+using FoundDevices = std::vector<DBusDeviceDescriptor>;
+
+struct PerformScan : std::enable_shared_from_this<PerformScan>
+{
+    PerformScan(nlohmann::json& systemConfiguration,
+                nlohmann::json& missingConfigurations,
+                std::list<nlohmann::json>& configurations,
+                sdbusplus::asio::object_server& objServer,
+                std::function<void()>&& callback);
+
+    void updateSystemConfiguration(const nlohmann::json& recordRef,
+                                   const std::string& probeName,
+                                   FoundDevices& foundDevices);
+    void run();
+    virtual ~PerformScan();
+    nlohmann::json& _systemConfiguration;
+    nlohmann::json& _missingConfigurations;
+    std::list<nlohmann::json> _configurations;
+    sdbusplus::asio::object_server& objServer;
+    std::function<void()> _callback;
+    bool _passed = false;
+    MapperGetSubTreeResponse dbusProbeObjects;
+    std::vector<std::string> passedProbes;
+};
+
+} // namespace scan
diff --git a/src/entity_manager/topology.cpp b/src/entity_manager/topology.cpp
new file mode 100644
index 0000000..ed827ad
--- /dev/null
+++ b/src/entity_manager/topology.cpp
@@ -0,0 +1,139 @@
+#include "topology.hpp"
+
+#include <iostream>
+
+void Topology::addBoard(const std::string& path, const std::string& boardType,
+                        const std::string& boardName,
+                        const nlohmann::json& exposesItem)
+{
+    auto findType = exposesItem.find("Type");
+    if (findType == exposesItem.end())
+    {
+        return;
+    }
+
+    boardNames.try_emplace(boardName, path);
+
+    PortType exposesType = findType->get<std::string>();
+
+    if (exposesType == "DownstreamPort")
+    {
+        auto findConnectsTo = exposesItem.find("ConnectsToType");
+        if (findConnectsTo == exposesItem.end())
+        {
+            std::cerr << "Board at path " << path
+                      << " is missing ConnectsToType" << std::endl;
+            return;
+        }
+        PortType connectsTo = findConnectsTo->get<std::string>();
+
+        downstreamPorts[connectsTo].emplace_back(path);
+        boardTypes[path] = boardType;
+        auto findPoweredBy = exposesItem.find("PowerPort");
+        if (findPoweredBy != exposesItem.end())
+        {
+            powerPaths.insert(path);
+        }
+    }
+    else if (exposesType.ends_with("Port"))
+    {
+        upstreamPorts[exposesType].emplace_back(path);
+        boardTypes[path] = boardType;
+    }
+}
+
+std::unordered_map<std::string, std::vector<Association>> Topology::getAssocs(
+    const std::map<Path, BoardName>& boards)
+{
+    std::unordered_map<std::string, std::vector<Association>> result;
+
+    // look at each upstream port type
+    for (const auto& upstreamPortPair : upstreamPorts)
+    {
+        auto downstreamMatch = downstreamPorts.find(upstreamPortPair.first);
+
+        if (downstreamMatch == downstreamPorts.end())
+        {
+            // no match
+            continue;
+        }
+
+        for (const Path& upstream : upstreamPortPair.second)
+        {
+            if (boardTypes[upstream] == "Chassis" ||
+                boardTypes[upstream] == "Board")
+            {
+                for (const Path& downstream : downstreamMatch->second)
+                {
+                    // The downstream path must be one we care about.
+                    if (boards.find(downstream) != boards.end())
+                    {
+                        result[downstream].emplace_back("contained_by",
+                                                        "containing", upstream);
+                        if (powerPaths.find(downstream) != powerPaths.end())
+                        {
+                            result[upstream].emplace_back(
+                                "powered_by", "powering", downstream);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+void Topology::remove(const std::string& boardName)
+{
+    // Remove the board from boardNames, and then using the path
+    // found in boardNames remove it from upstreamPorts and
+    // downstreamPorts.
+    auto boardFind = boardNames.find(boardName);
+    if (boardFind == boardNames.end())
+    {
+        return;
+    }
+
+    std::string boardPath = boardFind->second;
+
+    boardNames.erase(boardFind);
+
+    for (auto it = upstreamPorts.begin(); it != upstreamPorts.end();)
+    {
+        auto pathIt =
+            std::find(it->second.begin(), it->second.end(), boardPath);
+        if (pathIt != it->second.end())
+        {
+            it->second.erase(pathIt);
+        }
+
+        if (it->second.empty())
+        {
+            it = upstreamPorts.erase(it);
+        }
+        else
+        {
+            ++it;
+        }
+    }
+
+    for (auto it = downstreamPorts.begin(); it != downstreamPorts.end();)
+    {
+        auto pathIt =
+            std::find(it->second.begin(), it->second.end(), boardPath);
+        if (pathIt != it->second.end())
+        {
+            it->second.erase(pathIt);
+        }
+
+        if (it->second.empty())
+        {
+            it = downstreamPorts.erase(it);
+        }
+        else
+        {
+            ++it;
+        }
+    }
+}
diff --git a/src/entity_manager/topology.hpp b/src/entity_manager/topology.hpp
new file mode 100644
index 0000000..816704a
--- /dev/null
+++ b/src/entity_manager/topology.hpp
@@ -0,0 +1,33 @@
+#pragma once
+
+#include <nlohmann/json.hpp>
+
+#include <set>
+#include <unordered_map>
+
+using Association = std::tuple<std::string, std::string, std::string>;
+
+class Topology
+{
+  public:
+    explicit Topology() = default;
+
+    void addBoard(const std::string& path, const std::string& boardType,
+                  const std::string& boardName,
+                  const nlohmann::json& exposesItem);
+    std::unordered_map<std::string, std::vector<Association>> getAssocs(
+        const std::map<std::string, std::string>& boards);
+    void remove(const std::string& boardName);
+
+  private:
+    using Path = std::string;
+    using BoardType = std::string;
+    using BoardName = std::string;
+    using PortType = std::string;
+
+    std::unordered_map<PortType, std::vector<Path>> upstreamPorts;
+    std::unordered_map<PortType, std::vector<Path>> downstreamPorts;
+    std::set<Path> powerPaths;
+    std::unordered_map<Path, BoardType> boardTypes;
+    std::unordered_map<BoardName, Path> boardNames;
+};
