diff --git a/manager.hpp b/manager.hpp
index c96a4bc..65f4c83 100644
--- a/manager.hpp
+++ b/manager.hpp
@@ -1,10 +1,11 @@
 #pragma once
 
-#include <map>
-#include <set>
-#include <sdbusplus/bus.hpp>
 #include "ledlayout.hpp"
 
+#include <map>
+#include <sdbusplus/bus.hpp>
+#include <set>
+
 namespace phosphor
 {
 namespace led
@@ -20,162 +21,158 @@
  */
 class Manager
 {
-    public:
-        /** @brief Only need the default Manager */
-        Manager() = delete;
-        ~Manager() = default;
-        Manager(const Manager&) = delete;
-        Manager& operator=(const Manager&) = delete;
-        Manager(Manager&&) = delete;
-        Manager& operator=(Manager&&) = delete;
+  public:
+    /** @brief Only need the default Manager */
+    Manager() = delete;
+    ~Manager() = default;
+    Manager(const Manager&) = delete;
+    Manager& operator=(const Manager&) = delete;
+    Manager(Manager&&) = delete;
+    Manager& operator=(Manager&&) = delete;
 
-        /** @brief Special comparator for finding set difference */
-        static bool ledComp(const phosphor::led::Layout::LedAction& left,
-                            const phosphor::led::Layout::LedAction& right)
+    /** @brief Special comparator for finding set difference */
+    static bool ledComp(const phosphor::led::Layout::LedAction& left,
+                        const phosphor::led::Layout::LedAction& right)
+    {
+        // Example :
+        // If FIRST_1 is {fan0, 1, 1} and FIRST_2 is {fan0, 2, 2},
+        // with default priority of Blink, this comparator would return
+        // false. But considering the priority, this comparator would need
+        // to return true so that we consider appropriate set and in
+        // this case its {fan0, 1, 1}
+        if (left.name == right.name)
         {
-            // Example :
-            // If FIRST_1 is {fan0, 1, 1} and FIRST_2 is {fan0, 2, 2},
-            // with default priority of Blink, this comparator would return
-            // false. But considering the priority, this comparator would need
-            // to return true so that we consider appropriate set and in
-            // this case its {fan0, 1, 1}
-            if (left.name == right.name)
+            if (left.action == right.action)
             {
-                if (left.action == right.action)
-                {
-                    return false;
-                }
-                else
-                {
-                    return true;
-                }
+                return false;
             }
-            return left.name < right.name;
+            else
+            {
+                return true;
+            }
         }
+        return left.name < right.name;
+    }
 
-        /** @brief Comparator for finding LEDs to be DeAsserted */
-        static bool ledLess(const phosphor::led::Layout::LedAction& left,
-                            const phosphor::led::Layout::LedAction& right)
-        {
-            return left.name < right.name;
-        }
+    /** @brief Comparator for finding LEDs to be DeAsserted */
+    static bool ledLess(const phosphor::led::Layout::LedAction& left,
+                        const phosphor::led::Layout::LedAction& right)
+    {
+        return left.name < right.name;
+    }
 
-        /** @brief Comparator for helping unique_copy */
-        static bool ledEqual(const phosphor::led::Layout::LedAction& left,
-                             const phosphor::led::Layout::LedAction& right)
-        {
-            return left.name == right.name;
-        }
+    /** @brief Comparator for helping unique_copy */
+    static bool ledEqual(const phosphor::led::Layout::LedAction& left,
+                         const phosphor::led::Layout::LedAction& right)
+    {
+        return left.name == right.name;
+    }
 
-        using group = std::set<phosphor::led::Layout::LedAction>;
-        using LedLayout = std::map<std::string, group>;
+    using group = std::set<phosphor::led::Layout::LedAction>;
+    using LedLayout = std::map<std::string, group>;
 
-        /** @brief static global map constructed at compile time */
-        const LedLayout& ledMap;
+    /** @brief static global map constructed at compile time */
+    const LedLayout& ledMap;
 
-        /** @brief Refer the user supplied LED layout and sdbusplus handler
-         *
-         *  @param [in] bus       - sdbusplus handler
-         *  @param [in] LedLayout - LEDs group layout
-         */
-        Manager(sdbusplus::bus::bus& bus,
-                const LedLayout& ledLayout)
-                : ledMap(ledLayout),
-                  bus(bus)
-        {
-            // Nothing here
-        }
+    /** @brief Refer the user supplied LED layout and sdbusplus handler
+     *
+     *  @param [in] bus       - sdbusplus handler
+     *  @param [in] LedLayout - LEDs group layout
+     */
+    Manager(sdbusplus::bus::bus& bus, const LedLayout& ledLayout) :
+        ledMap(ledLayout), bus(bus)
+    {
+        // Nothing here
+    }
 
-        /** @brief Given a group name, applies the action on the group
-         *
-         *  @param[in]  path          -  dbus path of group
-         *  @param[in]  assert        -  Could be true or false
-         *  @param[in]  ledsAssert    -  LEDs that are to be asserted new
-         *                               or to a different state
-         *  @param[in]  ledsDeAssert  -  LEDs that are to be Deasserted
-         *
-         *  @return                   -  Success or exception thrown
-         */
-        bool setGroupState(const std::string& path, bool assert,
-                           group& ledsAssert, group& ledsDeAssert);
+    /** @brief Given a group name, applies the action on the group
+     *
+     *  @param[in]  path          -  dbus path of group
+     *  @param[in]  assert        -  Could be true or false
+     *  @param[in]  ledsAssert    -  LEDs that are to be asserted new
+     *                               or to a different state
+     *  @param[in]  ledsDeAssert  -  LEDs that are to be Deasserted
+     *
+     *  @return                   -  Success or exception thrown
+     */
+    bool setGroupState(const std::string& path, bool assert, group& ledsAssert,
+                       group& ledsDeAssert);
 
-        /** @brief Finds the set of LEDs to operate on and executes action
-         *
-         *  @param[in]  ledsAssert    -  LEDs that are to be asserted newly
-         *                               or to a different state
-         *  @param[in]  ledsDeAssert  -  LEDs that are to be Deasserted
-         *
-         *  @return: None
-         */
-        void driveLEDs(group& ledsAssert, group& ledsDeAssert);
+    /** @brief Finds the set of LEDs to operate on and executes action
+     *
+     *  @param[in]  ledsAssert    -  LEDs that are to be asserted newly
+     *                               or to a different state
+     *  @param[in]  ledsDeAssert  -  LEDs that are to be Deasserted
+     *
+     *  @return: None
+     */
+    void driveLEDs(group& ledsAssert, group& ledsDeAssert);
 
-    private:
-        /** @brief sdbusplus handler */
-        sdbusplus::bus::bus& bus;
+  private:
+    /** @brief sdbusplus handler */
+    sdbusplus::bus::bus& bus;
 
-        /** Map of physical LED path to service name */
-        std::map<std::string, std::string> phyLeds {};
+    /** Map of physical LED path to service name */
+    std::map<std::string, std::string> phyLeds{};
 
-        /** @brief Pointers to groups that are in asserted state */
-        std::set<const group*> assertedGroups;
+    /** @brief Pointers to groups that are in asserted state */
+    std::set<const group*> assertedGroups;
 
-        /** @brief Contains the highest priority actions for all
-         *         asserted LEDs.
-         */
-        group currentState;
+    /** @brief Contains the highest priority actions for all
+     *         asserted LEDs.
+     */
+    group currentState;
 
-        /** @brief Contains the set of all actions for asserted LEDs */
-        group combinedState;
+    /** @brief Contains the set of all actions for asserted LEDs */
+    group combinedState;
 
-        /** @brief Returns action string based on enum
-         *
-         *  @param[in]  action - Action enum
-         *
-         *  @return string equivalent of the passed in enumeration
-         */
-        static std::string getPhysicalAction(Layout::Action action);
+    /** @brief Returns action string based on enum
+     *
+     *  @param[in]  action - Action enum
+     *
+     *  @return string equivalent of the passed in enumeration
+     */
+    static std::string getPhysicalAction(Layout::Action action);
 
-        /** @brief Chooses appropriate action to be triggered on physical LED
-         *  and calls into function that applies the actual action.
-         *
-         *  @param[in]  objPath   -  dbus object path
-         *  @param[in]  action    -  Intended action to be triggered
-         *  @param[in]  dutyOn    -  Duty Cycle ON percentage
-         */
-        void drivePhysicalLED(const std::string& objPath,
-                              Layout::Action action,
-                              uint8_t dutyOn);
+    /** @brief Chooses appropriate action to be triggered on physical LED
+     *  and calls into function that applies the actual action.
+     *
+     *  @param[in]  objPath   -  dbus object path
+     *  @param[in]  action    -  Intended action to be triggered
+     *  @param[in]  dutyOn    -  Duty Cycle ON percentage
+     */
+    void drivePhysicalLED(const std::string& objPath, Layout::Action action,
+                          uint8_t dutyOn);
 
-        /** @brief Makes a dbus call to a passed in service name.
-         *  This is now the physical LED controller
-         *
-         *  @param[in]  service   -  dbus service name
-         *  @param[in]  objPath   -  dbus object path
-         *  @param[in]  property  -  property to be written to
-         *  @param[in]  value     -  Value to write
-         */
-        template <typename T>
-        void drivePhysicalLED(const std::string& service,
-                              const std::string& objPath,
-                              const std::string& property,
-                              const T& value)
-        {
-            sdbusplus::message::variant<T> data = value;
+    /** @brief Makes a dbus call to a passed in service name.
+     *  This is now the physical LED controller
+     *
+     *  @param[in]  service   -  dbus service name
+     *  @param[in]  objPath   -  dbus object path
+     *  @param[in]  property  -  property to be written to
+     *  @param[in]  value     -  Value to write
+     */
+    template <typename T>
+    void drivePhysicalLED(const std::string& service,
+                          const std::string& objPath,
+                          const std::string& property, const T& value)
+    {
+        sdbusplus::message::variant<T> data = value;
 
-            auto method = bus.new_method_call(service.c_str(), objPath.c_str(),
-                                              DBUS_PROPERTY_IFACE, "Set");
-            method.append(PHY_LED_IFACE);
-            method.append(property);
-            method.append(data);
+        auto method = bus.new_method_call(service.c_str(), objPath.c_str(),
+                                          DBUS_PROPERTY_IFACE, "Set");
+        method.append(PHY_LED_IFACE);
+        method.append(property);
+        method.append(data);
 
-            // There will be exceptions going forward and hence don't need a
-            // response
-            bus.call_noreply(method);
-            return;
-        }
+        // There will be exceptions going forward and hence don't need a
+        // response
+        bus.call_noreply(method);
+        return;
+    }
 
-        /** @brief Populates map of Physical LED paths to service name */
-        void populateObjectMap();
+    /** @brief Populates map of Physical LED paths to service name */
+    void populateObjectMap();
 };
 
 } // namespace led
