diff --git a/src/profiling/CounterDirectory.cpp b/src/profiling/CounterDirectory.cpp
index a848979..cef3d6a 100644
--- a/src/profiling/CounterDirectory.cpp
+++ b/src/profiling/CounterDirectory.cpp
@@ -4,8 +4,12 @@
 //
 
 #include "CounterDirectory.hpp"
+#include "ProfilingUtils.hpp"
 
 #include <armnn/Exceptions.hpp>
+#include <armnn/Conversion.hpp>
+
+#include <boost/format.hpp>
 
 namespace armnn
 {
@@ -13,149 +17,616 @@
 namespace profiling
 {
 
-CounterDirectory::CounterDirectory(uint16_t uid,
-                                   const std::string& name,
-                                   uint16_t deviceCount,
-                                   uint16_t counterCount,
-                                   uint16_t categoryCount)
-    : m_Uid(uid)
-    , m_Name(name)
-    , m_DeviceCount(deviceCount)
-    , m_CounterCount(counterCount)
-    , m_CategoryCount(categoryCount)
-    , m_DeviceIds(deviceCount)
-    , m_CounterIds(counterCount)
-    , m_CategoryIds(categoryCount)
-    , m_DeviceObjects(deviceCount)
-    , m_CounterObjects(counterCount)
-    , m_CategoryObjects(categoryCount)
-{}
-
-// Helper methods
-void CounterDirectory::CheckDeviceIndex(uint16_t index) const
+const Category* CounterDirectory::RegisterCategory(const std::string& categoryName,
+                                                   const Optional<uint16_t>& deviceUid,
+                                                   const Optional<uint16_t>& counterSetUid)
 {
-    if (index >= m_DeviceCount)
+    // Check that the given category name is valid
+    if (categoryName.empty() ||
+            !IsValidSwTraceString<SwTraceNameCharPolicy>(categoryName))
     {
-        throw InvalidArgumentException("Invalid device index");
+        throw InvalidArgumentException("Trying to register a category with an invalid name");
     }
-}
 
-void CounterDirectory::CheckCounterIndex(uint16_t index) const
-{
-    if (index >= m_CounterCount)
+    // Check that the given category is not already registered
+    if (CheckIfCategoryIsRegistered(categoryName))
     {
-        throw InvalidArgumentException("Invalid counter index");
+        throw InvalidArgumentException(
+                    boost::str(boost::format("Trying to register a category already registered (\"%1%\")")
+                               % categoryName));
     }
-}
 
-void CounterDirectory::CheckCategoryIndex(uint16_t index) const
-{
-    if (index >= m_CategoryCount)
+    // Check that a device with the given (optional) UID is already registered
+    uint16_t deviceUidValue = deviceUid.has_value() ? deviceUid.value() : 0;
+    if (deviceUidValue > 0)
     {
-        throw InvalidArgumentException("Invalid category index");
+        // Check that the (optional) device is already registered
+        if (!CheckIfDeviceIsRegistered(deviceUidValue))
+        {
+            throw InvalidArgumentException(
+                        boost::str(boost::format("Trying to connect a category (\"%1%\") to a device that is "
+                                                 "not registered (UID %2%)")
+                                   % categoryName
+                                   % deviceUidValue));
+        }
     }
+
+    // Check that a counter set with the given (optional) UID is already registered
+    uint16_t counterSetUidValue = counterSetUid.has_value() ? counterSetUid.value() : 0;
+    if (counterSetUidValue > 0)
+    {
+        // Check that the (optional) counter set is already registered
+        if (!CheckIfCounterSetIsRegistered(counterSetUidValue))
+        {
+            throw InvalidArgumentException(
+                        boost::str(boost::format("Trying to connect a category (name: \"%1%\") to a counter set "
+                                                 "that is not registered (UID: %2%)")
+                                   % categoryName
+                                   % counterSetUidValue));
+        }
+    }
+
+    // Create the category
+    CategoryPtr category = std::make_unique<Category>(categoryName, deviceUidValue, counterSetUidValue);
+    BOOST_ASSERT(category);
+
+    // Get the raw category pointer
+    const Category* categoryPtr = category.get();
+    BOOST_ASSERT(categoryPtr);
+
+    // Register the category
+    m_Categories.insert(std::move(category));
+
+    return categoryPtr;
 }
 
-// Getters for basic attributes
-uint16_t CounterDirectory::GetUid() const
+const Device* CounterDirectory::RegisterDevice(const std::string& deviceName,
+                                               uint16_t cores,
+                                               const Optional<std::string>& parentCategoryName)
 {
-    return m_Uid;
+    // Check that the given device name is valid
+    if (deviceName.empty() ||
+            !IsValidSwTraceString<SwTraceCharPolicy>(deviceName))
+    {
+        throw InvalidArgumentException("Trying to register a device with an invalid name");
+    }
+
+    // Check that a device with the given name is not already registered
+    if (CheckIfDeviceIsRegistered(deviceName))
+    {
+        throw InvalidArgumentException(
+                    boost::str(boost::format("Trying to register a device already registered (\"%1%\")")
+                               % deviceName));
+    }
+
+    // Peek the next UID, do not get an actual valid UID just now as we don't want to waste a good UID in case
+    // the registration fails. We'll get a proper one once we're sure that the device can be registered
+    uint16_t deviceUidPeek = GetNextUid(true);
+
+    // Check that a category with the given (optional) parent category name is already registered
+    Category* parentCategoryPtr = nullptr;
+    if (parentCategoryName.has_value())
+    {
+        // Get the (optional) parent category name
+        const std::string& parentCategoryNameValue = parentCategoryName.value();
+        if (parentCategoryNameValue.empty())
+        {
+            throw InvalidArgumentException(
+                        boost::str(boost::format("Trying to connect a device (name: \"%1%\") to an invalid "
+                                                 "parent category (name: \"%2%\")")
+                                   % deviceName
+                                   % parentCategoryNameValue));
+        }
+
+        // Check that the given parent category is already registered
+        auto categoryIt = FindCategory(parentCategoryNameValue);
+        if (categoryIt == m_Categories.end())
+        {
+            throw InvalidArgumentException(
+                        boost::str(boost::format("Trying to connect a device (name: \"%1%\") to a parent category that "
+                                                 "is not registered (name: \"%2%\")")
+                                   % deviceName
+                                   % parentCategoryNameValue));
+        }
+
+        // Get the parent category
+        const CategoryPtr& parentCategory = *categoryIt;
+        BOOST_ASSERT(parentCategory);
+
+        // Check that the given parent category is not already connected to another device
+        if (parentCategory->m_DeviceUid != 0 && parentCategory->m_DeviceUid != deviceUidPeek)
+        {
+            throw InvalidArgumentException(
+                        boost::str(boost::format("Trying to connect a device (UID: %1%) to a parent category that is "
+                                                 "already connected to a different device "
+                                                 "(category \"%2%\" connected to device %3%)")
+                                   % deviceUidPeek
+                                   % parentCategoryNameValue
+                                   % parentCategory->m_DeviceUid));
+        }
+
+        // The parent category can be associated to the device that is about to be registered.
+        // Get the raw pointer to the parent category (to be used later when the device is actually been
+        // registered, to make sure that the category is associated to an existing device)
+        parentCategoryPtr = parentCategory.get();
+    }
+
+    // Get the device UID
+    uint16_t deviceUid = GetNextUid();
+    BOOST_ASSERT(deviceUid == deviceUidPeek);
+
+    // Create the device
+    DevicePtr device = std::make_unique<Device>(deviceUid, deviceName, cores);
+    BOOST_ASSERT(device);
+
+    // Get the raw device pointer
+    const Device* devicePtr = device.get();
+    BOOST_ASSERT(devicePtr);
+
+    // Register the device
+    m_Devices.insert(std::make_pair(deviceUid, std::move(device)));
+
+    // Connect the device to the parent category, if required
+    if (parentCategoryPtr)
+    {
+        // Set the device UID in the parent category
+        parentCategoryPtr->m_DeviceUid = deviceUid;
+    }
+
+    return devicePtr;
 }
 
-const std::string& CounterDirectory::GetName() const
+const CounterSet* CounterDirectory::RegisterCounterSet(const std::string& counterSetName,
+                                                       uint16_t count,
+                                                       const Optional<std::string>& parentCategoryName)
 {
-    return m_Name;
+    // Check that the given counter set name is valid
+    if (counterSetName.empty() ||
+            !IsValidSwTraceString<SwTraceNameCharPolicy>(counterSetName))
+    {
+        throw InvalidArgumentException("Trying to register a counter set with an invalid name");
+    }
+
+    // Check that a counter set with the given name is not already registered
+    if (CheckIfCounterSetIsRegistered(counterSetName))
+    {
+        throw InvalidArgumentException(
+                    boost::str(boost::format("Trying to register a counter set already registered (\"%1%\")")
+                               % counterSetName));
+    }
+
+    // Peek the next UID, do not get an actual valid UID just now as we don't want to waste a good UID in case
+    // the registration fails. We'll get a proper one once we're sure that the counter set can be registered
+    uint16_t counterSetUidPeek = GetNextUid(true);
+
+    // Check that a category with the given (optional) parent category name is already registered
+    Category* parentCategoryPtr = nullptr;
+    if (parentCategoryName.has_value())
+    {
+        // Get the (optional) parent category name
+        const std::string& parentCategoryNameValue = parentCategoryName.value();
+        if (parentCategoryNameValue.empty())
+        {
+            throw InvalidArgumentException(
+                        boost::str(boost::format("Trying to connect a counter set (UID: %1%) to an invalid "
+                                                 "parent category (name: \"%2%\")")
+                                   % counterSetUidPeek
+                                   % parentCategoryNameValue));
+        }
+
+        // Check that the given parent category is already registered
+        auto it = FindCategory(parentCategoryNameValue);
+        if (it == m_Categories.end())
+        {
+            throw InvalidArgumentException(
+                        boost::str(boost::format("Trying to connect a counter set (UID: %1%) to a parent category "
+                                                 "that is not registered (name: \"%2%\")")
+                                   % counterSetUidPeek
+                                   % parentCategoryNameValue));
+        }
+
+        // Get the parent category
+        const CategoryPtr& parentCategory = *it;
+        BOOST_ASSERT(parentCategory);
+
+        // Check that the given parent category is not already connected to another counter set
+        if (parentCategory->m_CounterSetUid != 0 && parentCategory->m_CounterSetUid != counterSetUidPeek)
+        {
+            throw InvalidArgumentException(
+                        boost::str(boost::format("Trying to connect a counter set (UID: %1%) to a parent category "
+                                                 "that is already connected to a different counter set "
+                                                 "(category \"%2%\" connected to counter set %3%)")
+                                   % counterSetUidPeek
+                                   % parentCategoryNameValue
+                                   % parentCategory->m_CounterSetUid));
+        }
+
+        // The parent category can be associated to the counter set that is about to be registered.
+        // Get the raw pointer to the parent category (to be used later when the counter set is actually been
+        // registered, to make sure that the category is associated to an existing counter set)
+        parentCategoryPtr = parentCategory.get();
+    }
+
+    // Get the counter set UID
+    uint16_t counterSetUid = GetNextUid();
+    BOOST_ASSERT(counterSetUid == counterSetUidPeek);
+
+    // Create the counter set
+    CounterSetPtr counterSet = std::make_unique<CounterSet>(counterSetUid, counterSetName, count);
+    BOOST_ASSERT(counterSet);
+
+    // Get the raw counter set pointer
+    const CounterSet* counterSetPtr = counterSet.get();
+    BOOST_ASSERT(counterSetPtr);
+
+    // Register the counter set
+    m_CounterSets.insert(std::make_pair(counterSetUid, std::move(counterSet)));
+
+    // Connect the counter set to the parent category, if required
+    if (parentCategoryPtr)
+    {
+        // Set the counter set UID in the parent category
+        parentCategoryPtr->m_CounterSetUid = counterSetUid;
+    }
+
+    return counterSetPtr;
 }
 
-// Getters for counts
-uint16_t CounterDirectory::GetDeviceCount() const
+const Counter* CounterDirectory::RegisterCounter(const std::string& parentCategoryName,
+                                                 uint16_t counterClass,
+                                                 uint16_t interpolation,
+                                                 double multiplier,
+                                                 const std::string& name,
+                                                 const std::string& description,
+                                                 const Optional<std::string>& units,
+                                                 const Optional<uint16_t>& numberOfCores,
+                                                 const Optional<uint16_t>& deviceUid,
+                                                 const Optional<uint16_t>& counterSetUid)
 {
-    return m_DeviceCount;
+    // Check that the given parent category name is valid
+    if (parentCategoryName.empty() ||
+            !IsValidSwTraceString<SwTraceNameCharPolicy>(parentCategoryName))
+    {
+        throw InvalidArgumentException("Trying to register a counter with an invalid parent category name");
+    }
+
+    // Check that the given class is valid
+    if (counterClass != 0 && counterClass != 1)
+    {
+        throw InvalidArgumentException("Trying to register a counter with an invalid class");
+    }
+
+    // Check that the given interpolation is valid
+    if (interpolation != 0 && interpolation != 1)
+    {
+        throw InvalidArgumentException("Trying to register a counter with an invalid interpolation");
+    }
+
+    // Check that the given multiplier is valid
+    if (multiplier == .0f)
+    {
+        throw InvalidArgumentException("Trying to register a counter with an invalid multiplier");
+    }
+
+    // Check that the given name is valid
+    if (name.empty() ||
+            !IsValidSwTraceString<SwTraceCharPolicy>(name))
+    {
+        throw InvalidArgumentException("Trying to register a counter with an invalid name");
+    }
+
+    // Check that the given description is valid
+    if (description.empty() ||
+            !IsValidSwTraceString<SwTraceCharPolicy>(description))
+    {
+        throw InvalidArgumentException("Trying to register a counter with an invalid description");
+    }
+
+    // Check that the given units are valid
+    if (units.has_value()
+            && !IsValidSwTraceString<SwTraceNameCharPolicy>(units.value()))
+    {
+        throw InvalidArgumentException("Trying to register a counter with a invalid units");
+    }
+
+    // Check that the given parent category is registered
+    auto categoryIt = FindCategory(parentCategoryName);
+    if (categoryIt == m_Categories.end())
+    {
+        throw InvalidArgumentException(
+                    boost::str(boost::format("Trying to connect a counter to a category "
+                                             "that is not registered (name: \"%1%\")")
+                               % parentCategoryName));
+    }
+
+    // Get the parent category
+    const CategoryPtr& parentCategory = *categoryIt;
+    BOOST_ASSERT(parentCategory);
+
+    // Check that a counter with the given name is not already registered within the parent category
+    const std::vector<uint16_t>& parentCategoryCounters = parentCategory->m_Counters;
+    for (uint16_t parentCategoryCounterUid : parentCategoryCounters)
+    {
+        const Counter* parentCategoryCounter = GetCounter(parentCategoryCounterUid);
+        BOOST_ASSERT(parentCategoryCounter);
+
+        if (parentCategoryCounter->m_Name == name)
+        {
+            throw InvalidArgumentException(
+                        boost::str(boost::format("Trying to register a counter to category \"%1%\" with a name that "
+                                                 "is already used within that category (name: \"%2%\")")
+                                   % parentCategoryName
+                                   % name));
+        }
+    }
+
+    // Check that a counter set with the given (optional) UID is already registered
+    uint16_t counterSetUidValue = counterSetUid.has_value() ? counterSetUid.value() : 0;
+    if (counterSetUidValue > 0)
+    {
+        // Check that the (optional) counter set is already registered
+        if (!CheckIfCounterSetIsRegistered(counterSetUidValue))
+        {
+            throw InvalidArgumentException(
+                        boost::str(boost::format("Trying to connect a counter to a counter set that is "
+                                                 "not registered (counter set UID: %1%)")
+                                   % counterSetUidValue));
+        }
+    }
+
+    // Get the number of cores (this call may throw)
+    uint16_t deviceUidValue = deviceUid.has_value() ? deviceUid.value() : 0;
+    uint16_t deviceCores = GetNumberOfCores(numberOfCores, deviceUidValue, parentCategory);
+
+    // Get the counter UIDs and calculate the max counter UID
+    std::vector<uint16_t> counterUids = GetNextCounterUids(deviceCores);
+    BOOST_ASSERT(!counterUids.empty());
+    uint16_t maxCounterUid = deviceCores <= 1 ? counterUids.front() : counterUids.back();
+
+    // Get the counter units
+    const std::string unitsValue = units.has_value() ? units.value() : "";
+
+    // Create the counter
+    CounterPtr counter = std::make_shared<Counter>(counterUids.front(),
+                                                   maxCounterUid,
+                                                   counterClass,
+                                                   interpolation,
+                                                   multiplier,
+                                                   name,
+                                                   description,
+                                                   unitsValue,
+                                                   deviceUidValue,
+                                                   counterSetUidValue);
+    BOOST_ASSERT(counter);
+
+    // Get the raw counter pointer
+    const Counter* counterPtr = counter.get();
+    BOOST_ASSERT(counterPtr);
+
+    // Process multiple counters if necessary
+    for (uint16_t counterUid : counterUids)
+    {
+        // Connect the counter to the parent category
+        parentCategory->m_Counters.push_back(counterUid);
+
+        // Register the counter
+        m_Counters.insert(std::make_pair(counterUid, counter));
+    }
+
+    return counterPtr;
 }
 
-uint16_t CounterDirectory::GetCounterCount() const
+const Category* CounterDirectory::GetCategory(const std::string& categoryName) const
 {
-    return m_CounterCount;
+    auto it = FindCategory(categoryName);
+    if (it == m_Categories.end())
+    {
+        return nullptr;
+    }
+
+    const Category* category = it->get();
+    BOOST_ASSERT(category);
+
+    return category;
 }
 
-uint16_t CounterDirectory::GetCategoryCount() const
+const Device* CounterDirectory::GetDevice(uint16_t deviceUid) const
 {
-    return m_CategoryCount;
+    auto it = FindDevice(deviceUid);
+    if (it == m_Devices.end())
+    {
+        return nullptr;
+    }
+
+    const Device* device = it->second.get();
+    BOOST_ASSERT(device);
+    BOOST_ASSERT(device->m_Uid == deviceUid);
+
+    return device;
 }
 
-// Getters and setters for devices
-void CounterDirectory::GetDeviceValue(uint16_t index, uint32_t& value) const
+const CounterSet* CounterDirectory::GetCounterSet(uint16_t counterSetUid) const
 {
-    CheckDeviceIndex(index);
-    value = m_DeviceIds[index].load();
+    auto it = FindCounterSet(counterSetUid);
+    if (it == m_CounterSets.end())
+    {
+        return nullptr;
+    }
+
+    const CounterSet* counterSet = it->second.get();
+    BOOST_ASSERT(counterSet);
+    BOOST_ASSERT(counterSet->m_Uid == counterSetUid);
+
+    return counterSet;
 }
 
-void CounterDirectory::SetDeviceValue(uint16_t index, uint32_t value)
+const Counter* CounterDirectory::GetCounter(uint16_t counterUid) const
 {
-    CheckDeviceIndex(index);
-    m_DeviceIds[index].store(value);
+    auto it = FindCounter(counterUid);
+    if (it == m_Counters.end())
+    {
+        return nullptr;
+    }
+
+    const Counter* counter = it->second.get();
+    BOOST_ASSERT(counter);
+    BOOST_ASSERT(counter->m_Uid <= counterUid);
+    BOOST_ASSERT(counter->m_Uid <= counter->m_MaxCounterUid);
+
+    return counter;
 }
 
-void CounterDirectory::GetDeviceObject(uint16_t index, Device* device) const
+CategoriesIt CounterDirectory::FindCategory(const std::string& categoryName) const
 {
-    CheckDeviceIndex(index);
-    device = m_DeviceObjects[index].load();
+    return std::find_if(m_Categories.begin(), m_Categories.end(), [&categoryName](const CategoryPtr& category)
+    {
+        BOOST_ASSERT(category);
+
+        return category->m_Name == categoryName;
+    });
 }
 
-void CounterDirectory::SetDeviceObject(uint16_t index, Device* device)
+DevicesIt CounterDirectory::FindDevice(uint16_t deviceUid) const
 {
-    CheckDeviceIndex(index);
-    m_DeviceObjects[index].store(device);
+    return m_Devices.find(deviceUid);
 }
 
-// Getters and setters for counters
-void CounterDirectory::GetCounterValue(uint16_t index, uint32_t& value) const
+DevicesIt CounterDirectory::FindDevice(const std::string& deviceName) const
 {
-    CheckCounterIndex(index);
-    value = m_CounterIds[index].load();
+    return std::find_if(m_Devices.begin(), m_Devices.end(), [&deviceName](const auto& pair)
+    {
+        BOOST_ASSERT(pair.second);
+        BOOST_ASSERT(pair.second->m_Uid == pair.first);
+
+        return pair.second->m_Name == deviceName;
+    });
 }
 
-void CounterDirectory::SetCounterValue(uint16_t index, uint32_t value)
+CounterSetsIt CounterDirectory::FindCounterSet(uint16_t counterSetUid) const
 {
-    CheckCounterIndex(index);
-    m_CounterIds[index].store(value);
+    return m_CounterSets.find(counterSetUid);
 }
 
-void CounterDirectory::GetCounterObject(uint16_t index, Counter* counter) const
+CounterSetsIt CounterDirectory::FindCounterSet(const std::string& counterSetName) const
 {
-    CheckCounterIndex(index);
-    counter = m_CounterObjects[index].load();
+    return std::find_if(m_CounterSets.begin(), m_CounterSets.end(), [&counterSetName](const auto& pair)
+    {
+        BOOST_ASSERT(pair.second);
+        BOOST_ASSERT(pair.second->m_Uid == pair.first);
+
+        return pair.second->m_Name == counterSetName;
+    });
 }
 
-void CounterDirectory::SetCounterObject(uint16_t index, Counter* counter)
+CountersIt CounterDirectory::FindCounter(uint16_t counterUid) const
 {
-    CheckCounterIndex(index);
-    m_CounterObjects[index].store(counter);
+    return m_Counters.find(counterUid);
 }
 
-// Getters and setters for categories
-void CounterDirectory::GetCategoryValue(uint16_t index, uint32_t& value) const
+bool CounterDirectory::CheckIfCategoryIsRegistered(const std::string& categoryName) const
 {
-    CheckCategoryIndex(index);
-    value = m_CategoryIds[index].load();
+    auto it = FindCategory(categoryName);
+
+    return it != m_Categories.end();
 }
 
-void CounterDirectory::SetCategoryValue(uint16_t index, uint32_t value)
+bool CounterDirectory::CheckIfDeviceIsRegistered(uint16_t deviceUid) const
 {
-    CheckCategoryIndex(index);
-    m_CategoryIds[index].store(value);
+    auto it = FindDevice(deviceUid);
+
+    return it != m_Devices.end();
 }
 
-void CounterDirectory::GetCategoryObject(uint16_t index, Category* category) const
+bool CounterDirectory::CheckIfDeviceIsRegistered(const std::string& deviceName) const
 {
-    CheckCategoryIndex(index);
-    category = m_CategoryObjects[index].load();
+    auto it = FindDevice(deviceName);
+
+    return it != m_Devices.end();
 }
 
-void CounterDirectory::SetCategoryObject(uint16_t index, Category* category)
+bool CounterDirectory::CheckIfCounterSetIsRegistered(uint16_t counterSetUid) const
 {
-    CheckCategoryIndex(index);
-    m_CategoryObjects[index].store(category);
+    auto it = FindCounterSet(counterSetUid);
+
+    return it != m_CounterSets.end();
+}
+
+bool CounterDirectory::CheckIfCounterSetIsRegistered(const std::string& counterSetName) const
+{
+    auto it = FindCounterSet(counterSetName);
+
+    return it != m_CounterSets.end();
+}
+
+uint16_t CounterDirectory::GetNumberOfCores(const Optional<uint16_t>& numberOfCores,
+                                            uint16_t deviceUid,
+                                            const CategoryPtr& parentCategory)
+{
+    BOOST_ASSERT(parentCategory);
+
+    // To get the number of cores, apply the following rules:
+    //
+    // 1. If numberOfCores is set then take it as the deviceCores value
+    // 2. If numberOfCores is not set then check to see if this counter is directly associated with a device,
+    //    if so then that devices number of cores is taken as the deviceCores value
+    // 3. If neither of the above is set then look at the category to see if it has a device associated with it,
+    //    if it does then take that device's numberOfCores as the deviceCores value
+    // 4. If none of the above holds then set deviceCores to zero
+
+    // 1. If numberOfCores is set then take it as the deviceCores value
+    if (numberOfCores.has_value())
+    {
+        // Get the number of cores
+        return numberOfCores.value();
+    }
+
+    // 2. If numberOfCores is not set then check to see if this counter is directly associated with a device,
+    //    if so then that devices number of cores is taken as the deviceCores value
+    if (deviceUid > 0)
+    {
+        // Check that the (optional) device is already registered
+        auto deviceIt = FindDevice(deviceUid);
+        if (deviceIt == m_Devices.end())
+        {
+            throw InvalidArgumentException(
+                        boost::str(boost::format("Trying to connect a counter to a device that is "
+                                                 "not registered (device UID %1%)")
+                                   % deviceUid));
+        }
+
+        // Get the associated device
+        const DevicePtr& device = deviceIt->second;
+        BOOST_ASSERT(device);
+
+        // Get the number of cores of the associated device
+        return device->m_Cores;
+    }
+
+    // 3. If neither of the above is set then look at the category to see if it has a device associated with it,
+    //    if it does then take that device's numberOfCores as the deviceCores value
+    uint16_t parentCategoryDeviceUid = parentCategory->m_DeviceUid;
+    if (parentCategoryDeviceUid > 0)
+    {
+        // Check that the device associated to the parent category is already registered
+        auto deviceIt = FindDevice(parentCategoryDeviceUid);
+        if (deviceIt == m_Devices.end())
+        {
+            throw InvalidArgumentException(
+                        boost::str(boost::format("Trying to get the number of cores from a device that is "
+                                                 "not registered (device UID %1%)")
+                                   % parentCategoryDeviceUid));
+        }
+
+        // Get the associated device
+        const DevicePtr& device = deviceIt->second;
+        BOOST_ASSERT(device);
+
+        // Get the number of cores of the device associated to the parent category
+        return device->m_Cores;
+    }
+
+    // 4. If none of the above holds then set deviceCores to zero
+    return 0;
 }
 
 } // namespace profiling
