diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/ServerDevicesDiscovery.java b/drivers/server/src/main/java/org/onosproject/drivers/server/ServerDevicesDiscovery.java
new file mode 100644
index 0000000..c5934f5
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/ServerDevicesDiscovery.java
@@ -0,0 +1,926 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.
+ */
+
+package org.onosproject.drivers.server;
+
+import org.onosproject.drivers.server.behavior.CpuStatisticsDiscovery;
+import org.onosproject.drivers.server.behavior.MonitoringStatisticsDiscovery;
+import org.onosproject.drivers.server.devices.CpuDevice;
+import org.onosproject.drivers.server.devices.CpuVendor;
+import org.onosproject.drivers.server.devices.NicDevice;
+import org.onosproject.drivers.server.devices.NicRxFilter;
+import org.onosproject.drivers.server.devices.NicRxFilter.RxFilter;
+import org.onosproject.drivers.server.devices.ServerDeviceDescription;
+import org.onosproject.drivers.server.devices.RestServerSBDevice;
+import org.onosproject.drivers.server.stats.CpuStatistics;
+import org.onosproject.drivers.server.stats.MonitoringStatistics;
+import org.onosproject.drivers.server.stats.TimingStatistics;
+
+import org.onosproject.drivers.server.impl.devices.DefaultCpuDevice;
+import org.onosproject.drivers.server.impl.devices.DefaultNicDevice;
+import org.onosproject.drivers.server.impl.devices.DefaultRestServerSBDevice;
+import org.onosproject.drivers.server.impl.devices.DefaultServerDeviceDescription;
+import org.onosproject.drivers.server.impl.stats.DefaultCpuStatistics;
+import org.onosproject.drivers.server.impl.stats.DefaultMonitoringStatistics;
+import org.onosproject.drivers.server.impl.stats.DefaultTimingStatistics;
+
+import org.onlab.packet.ChassisId;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.behaviour.DevicesDiscovery;
+import org.onosproject.net.device.DeviceDescription;
+import org.onosproject.net.device.DeviceDescriptionDiscovery;
+import org.onosproject.net.device.DefaultPortStatistics;
+import org.onosproject.net.device.DefaultPortDescription;
+import org.onosproject.net.device.PortDescription;
+import org.onosproject.net.device.PortStatistics;
+import org.onosproject.net.device.PortStatisticsDiscovery;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.protocol.rest.RestSBDevice;
+import org.onosproject.protocol.rest.RestSBDevice.AuthenticationScheme;
+
+import org.slf4j.Logger;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.ImmutableList;
+
+import javax.ws.rs.ProcessingException;
+import java.io.InputStream;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Discovers the device details of
+ * REST-based commodity server devices.
+ */
+public class ServerDevicesDiscovery extends BasicServerDriver
+        implements  DevicesDiscovery, DeviceDescriptionDiscovery,
+                    PortStatisticsDiscovery, CpuStatisticsDiscovery,
+                    MonitoringStatisticsDiscovery {
+
+    private final Logger log = getLogger(getClass());
+
+    /**
+     * Resource endpoints of the server agent (REST server-side).
+     */
+    private static final String RESOURCE_DISCOVERY_URL   = BASE_URL + "/resources";
+    private static final String GLOBAL_STATS_URL         = BASE_URL + "/stats";
+    private static final String SERVICE_CHAINS_STATS_URL = BASE_URL + "/chains_stats";  // + /ID
+
+    /**
+     * Parameters to be exchanged with the server's agent.
+     */
+    private static final String PARAM_ID               = "id";
+    private static final String PARAM_CPUS             = "cpus";
+    private static final String PARAM_MANUFACTURER     = "manufacturer";
+    private static final String PARAM_HW_VENDOR        = "hwVersion";
+    private static final String PARAM_SW_VENDOR        = "swVersion";
+    private static final String PARAM_SERIAL           = "serial";
+    private static final String PARAM_NICS             = "nics";
+    private static final String PARAM_TIMING_STATS     = "timing_stats";
+    private static final String PARAM_TIMING_AUTOSCALE = "autoscale_timing_stats";
+
+    private static final String NIC_PARAM_ID               = "id";
+    private static final String NIC_PARAM_PORT_TYPE        = "portType";
+    private static final String NIC_PARAM_PORT_TYPE_FIBER  = "fiber";
+    private static final String NIC_PARAM_PORT_TYPE_COPPER = "copper";
+    private static final String NIC_PARAM_SPEED            = "speed";
+    private static final String NIC_PARAM_STATUS           = "status";
+    private static final String NIC_PARAM_HW_ADDR          = "hwAddr";
+    private static final String NIC_PARAM_RX_FILTER        = "rxFilter";
+    private static final String NIC_PARAM_RX_METHOD        = "method";
+    private static final String NIC_PARAM_RX_METHOD_VALUES = "values";
+
+    /**
+     * NIC statistics.
+     */
+    private static final String NIC_STATS_TX_COUNT  = "txCount";
+    private static final String NIC_STATS_TX_BYTES  = "txBytes";
+    private static final String NIC_STATS_TX_DROPS  = "txDropped";
+    private static final String NIC_STATS_TX_ERRORS = "txErrors";
+    private static final String NIC_STATS_RX_COUNT  = "rxCount";
+    private static final String NIC_STATS_RX_BYTES  = "rxBytes";
+    private static final String NIC_STATS_RX_DROPS  = "rxDropped";
+    private static final String NIC_STATS_RX_ERRORS = "rxErrors";
+
+    /**
+     * CPU statistics.
+     */
+    private static final String CPU_PARAM_ID        = "id";
+    private static final String CPU_PARAM_VENDOR    = "vendor";
+    private static final String CPU_PARAM_FREQUENCY = "frequency";
+    private static final String CPU_PARAM_LOAD      = "load";
+    private static final String CPU_PARAM_STATUS    = "busy";
+    private static final String CPU_STATS_BUSY_CPUS = "busyCpus";
+    private static final String CPU_STATS_FREE_CPUS = "freeCpus";
+
+    /**
+     * Timing statistics.
+     */
+    private static final String TIMING_PARAM_PARSE     = "parse";
+    private static final String TIMING_PARAM_LAUNCH    = "launch";
+    private static final String TIMING_PARAM_AUTOSCALE = "autoscale";
+
+    /**
+     * Auxiliary constants.
+     */
+    private static final short  DISCOVERY_RETRIES  = 3;
+    private static final String CPU_VENDOR_NULL    = "Unsupported CPU vendor" +
+        " Choose one in: " + BasicServerDriver.enumTypesToString(CpuVendor.class);
+    private static final String NIC_RX_FILTER_NULL = "Unsupported NIC Rx filter" +
+        " Choose one in: " + BasicServerDriver.enumTypesToString(RxFilter.class);
+
+    /**
+     * Port types that usually appear in commodity servers.
+     */
+    public static final Map<String, Port.Type> PORT_TYPE_MAP =
+        Collections.unmodifiableMap(
+            new HashMap<String, Port.Type>() {
+                {
+                    put(NIC_PARAM_PORT_TYPE_FIBER,  Port.Type.FIBER);
+                    put(NIC_PARAM_PORT_TYPE_COPPER, Port.Type.COPPER);
+                }
+            }
+        );
+
+    /**
+     * Constructs server device discovery.
+     */
+    public ServerDevicesDiscovery() {
+        super();
+        log.debug("Started");
+    }
+
+    @Override
+    public Set<DeviceId> deviceIds() {
+        // Set of devices to return
+        Set<DeviceId> devices = new HashSet<DeviceId>();
+
+        DeviceId deviceId = getHandler().data().deviceId();
+        checkNotNull(deviceId, DEVICE_ID_NULL);
+        devices.add(deviceId);
+
+        return devices;
+    }
+
+    @Override
+    public DeviceDescription deviceDetails(DeviceId deviceId) {
+        return getDeviceDetails(deviceId);
+    }
+
+    @Override
+    public DeviceDescription discoverDeviceDetails() {
+        return getDeviceDetails(null);
+    }
+
+    /**
+     * Query a server to retrieve its features.
+     *
+     * @param deviceId the device ID to be queried
+     * @return a DeviceDescription with the device's features
+     */
+    private DeviceDescription getDeviceDetails(DeviceId deviceId) {
+        // Create a description for this server device
+        ServerDeviceDescription desc = null;
+
+        // Retrieve the device ID, if null given
+        if (deviceId == null) {
+            deviceId = getHandler().data().deviceId();
+            checkNotNull(deviceId, DEVICE_ID_NULL);
+        }
+
+        // Get the device
+        RestSBDevice device = getController().getDevice(deviceId);
+        checkNotNull(device, DEVICE_NULL);
+
+        // Hit the path that provides the server's resources
+        InputStream response = null;
+        try {
+            response = getController().get(
+                deviceId,
+                RESOURCE_DISCOVERY_URL,
+                JSON
+            );
+        } catch (ProcessingException pEx) {
+            log.error("Failed to discover the device details of: {}", deviceId);
+            return desc;
+        }
+
+        // Load the JSON into objects
+        ObjectMapper mapper = new ObjectMapper();
+        Map<String, Object> jsonMap = null;
+        JsonNode jsonNode = null;
+        ObjectNode objNode = null;
+        try {
+            jsonMap  = mapper.readValue(response, Map.class);
+            jsonNode = mapper.convertValue(jsonMap, JsonNode.class);
+            objNode = (ObjectNode) jsonNode;
+        } catch (IOException ioEx) {
+            log.error("Failed to discover the device details of: {}", deviceId);
+            return desc;
+        }
+
+        if (jsonMap == null) {
+            log.error("Failed to discover the device details of: {}", deviceId);
+            return desc;
+        }
+
+        // Get all the attributes
+        String id     = get(jsonNode, PARAM_ID);
+        String vendor = get(jsonNode, PARAM_MANUFACTURER);
+        String hw     = get(jsonNode, PARAM_HW_VENDOR);
+        String sw     = get(jsonNode, PARAM_SW_VENDOR);
+        String serial = get(jsonNode, PARAM_SERIAL);
+
+        // CPUs are composite attributes
+        Set<CpuDevice> cpuSet = new HashSet<CpuDevice>();
+        JsonNode cpuNode = objNode.path(PARAM_CPUS);
+
+        // Construct CPU objects
+        for (JsonNode cn : cpuNode) {
+            ObjectNode cpuObjNode = (ObjectNode) cn;
+
+            // All the CPU attributes
+            int           cpuId = cpuObjNode.path(CPU_PARAM_ID).asInt();
+            String cpuVendorStr = get(cn, CPU_PARAM_VENDOR);
+            long   cpuFrequency = cpuObjNode.path(CPU_PARAM_FREQUENCY).asLong();
+
+            // Verify that this is a valid vendor
+            CpuVendor cpuVendor = CpuVendor.getByName(cpuVendorStr);
+            checkNotNull(cpuVendor, CPU_VENDOR_NULL);
+
+            // Construct a CPU device
+            CpuDevice cpu = new DefaultCpuDevice(cpuId, cpuVendor, cpuFrequency);
+
+            // Add it to the set
+            cpuSet.add(cpu);
+        }
+
+        // NICs are composite attributes too
+        Set<NicDevice> nicSet = new HashSet<NicDevice>();
+        JsonNode nicNode = objNode.path(PARAM_NICS);
+
+        // Construct NIC objects
+        for (JsonNode nn : nicNode) {
+            ObjectNode nicObjNode = (ObjectNode) nn;
+
+            // All the NIC attributes
+            String nicId       = get(nn, NIC_PARAM_ID);
+            int port           = Integer.parseInt(nicId.replaceAll("\\D+", ""));
+            long speed         = nicObjNode.path(NIC_PARAM_SPEED).asLong();
+            String portTypeStr = get(nn, NIC_PARAM_PORT_TYPE);
+            Port.Type portType = PORT_TYPE_MAP.get(portTypeStr);
+            if (portType == null) {
+                throw new RuntimeException(
+                    portTypeStr + " is not a valid port type for NIC " + nicId
+                );
+            }
+            boolean status     = nicObjNode.path(NIC_PARAM_STATUS).asInt() > 0;
+            String hwAddr      = get(nn, NIC_PARAM_HW_ADDR);
+            JsonNode tagNode   = nicObjNode.path(NIC_PARAM_RX_FILTER);
+            if (tagNode == null) {
+                throw new RuntimeException(
+                    "The Rx filters of NIC " + nicId + " are not reported"
+                );
+            }
+
+            // Convert the JSON list into an array of strings
+            List<String> rxFilters = null;
+            try {
+                rxFilters = mapper.readValue(
+                    tagNode.traverse(),
+                    new TypeReference<ArrayList<String>>() { }
+                );
+            } catch (IOException ioEx) {
+                continue;
+            }
+
+            // Parse the array of strings and create an RxFilter object
+            NicRxFilter rxFilterMechanism = new NicRxFilter();
+            for (String s : rxFilters) {
+                // Verify that this is a valid Rx filter
+                RxFilter rf = RxFilter.getByName(s);
+                checkNotNull(rf, NIC_RX_FILTER_NULL);
+
+                rxFilterMechanism.addRxFilter(rf);
+            }
+
+            // Construct a NIC device for this server
+            NicDevice nic = new DefaultNicDevice(
+                nicId, port, portType, speed, status, hwAddr, rxFilterMechanism
+            );
+
+            // Add it to the set
+            nicSet.add(nic);
+        }
+
+        /**
+         * Construct a complete server device object.
+         * Lists of NICs and CPUs extend the information
+         * already in RestSBDevice (parent class).
+         */
+        RestServerSBDevice dev = new DefaultRestServerSBDevice(
+            device.ip(), device.port(), device.username(),
+            device.password(), device.protocol(), device.url(),
+            device.isActive(), device.testUrl().toString(),
+            vendor, hw, sw, AuthenticationScheme.BASIC, "",
+            cpuSet, nicSet
+        );
+        checkNotNull(dev, DEVICE_NULL);
+
+        // Updates the controller with the complete device information
+        getController().removeDevice(deviceId);
+        getController().addDevice((RestSBDevice) dev);
+
+        /**
+         * TODO: Create a new Device type
+         * Device.Type.COMMODITY_SERVER
+         * and add a new icon in the GUI.
+         */
+        try {
+            desc = new DefaultServerDeviceDescription(
+                new URI(id), Device.Type.OTHER, vendor,
+                hw, sw, serial, new ChassisId(),
+                cpuSet, nicSet, DefaultAnnotations.EMPTY
+            );
+        } catch (URISyntaxException uEx) {
+            log.error(
+                "Failed to create a server device description for: {}", deviceId
+            );
+            return null;
+        }
+
+        log.info("Device's {} details sent to the controller", deviceId);
+
+        return desc;
+    }
+
+    @Override
+    public List<PortDescription> discoverPortDetails() {
+        // List of port descriptions to return
+        List<PortDescription> portDescriptions = Lists.newArrayList();
+
+        // Retrieve the device ID
+        DeviceId deviceId = getHandler().data().deviceId();
+        checkNotNull(deviceId, DEVICE_ID_NULL);
+        // .. and object
+        RestServerSBDevice device = null;
+
+        /*
+         * In case this method is called before discoverDeviceDetails,
+         * there is missing information to be gathered.
+         */
+        short i = 0;
+        while ((device == null) && (i < DISCOVERY_RETRIES)) {
+            i++;
+
+            try {
+                device = (RestServerSBDevice) getController().getDevice(deviceId);
+            } catch (ClassCastException ccEx) {
+                try {
+                    Thread.sleep(1);
+                } catch (InterruptedException intEx) {
+                    // Just retry
+                } finally {
+                    continue;
+                }
+            }
+
+            // No device
+            if (device == null) {
+                // This method will add the device to the RestSBController
+                this.getDeviceDetails(deviceId);
+            }
+        }
+
+        if ((device == null) || (device.nics() == null)) {
+            log.error("No ports available on {}", deviceId);
+            return ImmutableList.copyOf(portDescriptions);
+        }
+
+        // Sorted list of NIC ports
+        Set<NicDevice> nics = new TreeSet(device.nics());
+
+        // Iterate through the NICs of this device to populate the list
+        long portCounter = 0;
+        for (NicDevice nic : nics) {
+            // The port number of this NIC
+            PortNumber portNumber = PortNumber.portNumber(++portCounter);
+
+            // Include the name of this device as an annotation
+            DefaultAnnotations.Builder annotations = DefaultAnnotations.builder()
+                                .set(AnnotationKeys.PORT_NAME, nic.id());
+
+            // Create a port description and add it to the list
+            portDescriptions.add(
+                new DefaultPortDescription(
+                    portNumber, nic.status(),
+                    nic.portType(), nic.speed(),
+                    annotations.build()
+                )
+            );
+
+            log.info(
+                "Port discovery on device {}: NIC {} is {} at {} Mbps",
+                deviceId, nic.port(), nic.status() ? "up" : "down",
+                nic.speed()
+            );
+        }
+
+        return ImmutableList.copyOf(portDescriptions);
+    }
+
+    @Override
+    public Collection<PortStatistics> discoverPortStatistics() {
+        // Retrieve the device ID
+        DeviceId deviceId = getHandler().data().deviceId();
+        checkNotNull(deviceId, DEVICE_ID_NULL);
+
+        // Get port statistics for this device
+        return getPortStatistics(deviceId);
+    }
+
+    /**
+     * Query a server to retrieve its port statistics.
+     *
+     * @param deviceId the device ID to be queried
+     * @return list of (per port) PortStatistics
+     */
+    private Collection<PortStatistics> getPortStatistics(DeviceId deviceId) {
+        // List of port statistics to return
+        Collection<PortStatistics> portStats = null;
+
+        // Get global monitoring statistics
+        MonitoringStatistics monStats = getGlobalMonitoringStatistics(deviceId);
+        if (monStats == null) {
+            return portStats;
+        }
+
+        // Filter out the NIC statistics
+        portStats = monStats.nicStatisticsAll();
+        if (portStats == null) {
+            return portStats;
+        }
+
+        log.debug("Port statistics: {}", portStats.toString());
+
+        return portStats;
+    }
+
+    @Override
+    public Collection<CpuStatistics> discoverCpuStatistics() {
+        // Retrieve the device ID
+        DeviceId deviceId = getHandler().data().deviceId();
+        checkNotNull(deviceId, DEVICE_ID_NULL);
+
+        // Get CPU statistics for this device
+        return getCpuStatistics(deviceId);
+    }
+
+    /**
+     * Query a server to retrieve its CPU statistics.
+     *
+     * @param deviceId the device ID to be queried
+     * @return list of (per core) CpuStatistics
+     */
+     private Collection<CpuStatistics> getCpuStatistics(DeviceId deviceId) {
+        // List of port statistics to return
+        Collection<CpuStatistics> cpuStats = null;
+
+        // Get global monitoring statistics
+        MonitoringStatistics monStats = getGlobalMonitoringStatistics(deviceId);
+        if (monStats == null) {
+            return cpuStats;
+        }
+
+        // Filter out the CPU statistics
+        cpuStats = monStats.cpuStatisticsAll();
+        if (cpuStats == null) {
+            return cpuStats;
+        }
+
+        log.debug("CPU statistics: {}", cpuStats.toString());
+
+        return cpuStats;
+    }
+
+    @Override
+    public MonitoringStatistics discoverGlobalMonitoringStatistics() {
+        // Retrieve the device ID
+        DeviceId deviceId = getHandler().data().deviceId();
+        checkNotNull(deviceId, DEVICE_ID_NULL);
+
+        // Get global monitoring statistics for this device
+        return getGlobalMonitoringStatistics(deviceId);
+    }
+
+    /**
+     * Query a server to retrieve its global monitoring statistics.
+     *
+     * @param deviceId the device ID to be queried
+     * @return global monitoring statistics
+     */
+     private MonitoringStatistics getGlobalMonitoringStatistics(DeviceId deviceId) {
+        // Monitoring statistics to return
+        MonitoringStatistics monStats = null;
+
+        RestServerSBDevice device = null;
+        try {
+            device = (RestServerSBDevice) getController().getDevice(deviceId);
+        } catch (ClassCastException ccEx) {
+            log.error(
+                "Failed to retrieve global monitoring statistics from device {}",
+                deviceId
+            );
+            return monStats;
+        }
+        checkNotNull(device, DEVICE_NULL);
+
+        // Hit the path that provides the server's global resources
+        InputStream response = null;
+        try {
+            response = getController().get(
+                deviceId,
+                GLOBAL_STATS_URL,
+                JSON
+            );
+        } catch (ProcessingException pEx) {
+            log.error(
+                "Failed to retrieve global monitoring statistics from device {}",
+                deviceId
+            );
+            return monStats;
+        }
+
+        // Load the JSON into objects
+        ObjectMapper mapper = new ObjectMapper();
+        Map<String, Object> jsonMap = null;
+        JsonNode jsonNode  = null;
+        ObjectNode objNode = null;
+        try {
+            jsonMap  = mapper.readValue(response, Map.class);
+            jsonNode = mapper.convertValue(jsonMap, JsonNode.class);
+            objNode = (ObjectNode) jsonNode;
+        } catch (IOException ioEx) {
+            log.error(
+                "Failed to retrieve global monitoring statistics from device {}",
+                deviceId
+            );
+            return monStats;
+        }
+
+        if (jsonMap == null) {
+            log.error(
+                "Failed to retrieve global monitoring statistics from device {}",
+                deviceId
+            );
+            return monStats;
+        }
+
+        // Get high-level CPU statistics
+        int busyCpus = objNode.path(CPU_STATS_BUSY_CPUS).asInt();
+        int freeCpus = objNode.path(CPU_STATS_FREE_CPUS).asInt();
+
+        // Get a list of CPU statistics per core
+        Collection<CpuStatistics> cpuStats = parseCpuStatistics(deviceId, objNode);
+
+        // Get a list of port statistics
+        Collection<PortStatistics> nicStats = parseNicStatistics(deviceId, objNode);
+
+        // Get zero timing statistics
+        TimingStatistics timinsgStats = getZeroTimingStatistics();
+
+        // Ready to construct the grand object
+        DefaultMonitoringStatistics.Builder statsBuilder =
+            DefaultMonitoringStatistics.builder();
+
+        statsBuilder.setDeviceId(deviceId)
+                .setTimingStatistics(timinsgStats)
+                .setCpuStatistics(cpuStats)
+                .setNicStatistics(nicStats)
+                .build();
+
+        monStats = statsBuilder.build();
+
+        log.debug("Global monitoring statistics: {}", monStats.toString());
+
+        return monStats;
+    }
+
+    @Override
+    public MonitoringStatistics discoverMonitoringStatistics(URI tcId) {
+        // Retrieve the device ID
+        DeviceId deviceId = getHandler().data().deviceId();
+        checkNotNull(deviceId, DEVICE_ID_NULL);
+
+        // Get resource-specific monitoring statistics for this device
+        return getMonitoringStatistics(deviceId, tcId);
+    }
+
+    /**
+     * Query a server to retrieve monitoring statistics for a
+     * specific resource (i.e., traffic class).
+     *
+     * @param deviceId the device ID to be queried
+     * @param tcId the ID of the traffic class to be monitored
+     * @return resource-specific monitoring statistics
+     */
+     private MonitoringStatistics getMonitoringStatistics(DeviceId deviceId, URI tcId) {
+        // Monitoring statistics to return
+        MonitoringStatistics monStats = null;
+
+        RestServerSBDevice device = null;
+        try {
+            device = (RestServerSBDevice) getController().getDevice(deviceId);
+        } catch (ClassCastException ccEx) {
+            log.error(
+                "Failed to retrieve monitoring statistics from device {}",
+                deviceId
+            );
+            return monStats;
+        }
+        checkNotNull(device, DEVICE_NULL);
+
+        // Create a resource-specific URL
+        String scUrl = SERVICE_CHAINS_STATS_URL + "/" + tcId.toString();
+
+        // Hit the path that provides the server's specific resources
+        InputStream response = null;
+        try {
+            response = getController().get(
+                deviceId,
+                scUrl,
+                JSON
+            );
+        } catch (ProcessingException pEx) {
+            log.error(
+                "Failed to retrieve monitoring statistics from device {}",
+                deviceId
+            );
+            return monStats;
+        }
+
+        // Load the JSON into objects
+        ObjectMapper mapper = new ObjectMapper();
+        Map<String, Object> jsonMap = null;
+        JsonNode jsonNode  = null;
+        ObjectNode objNode = null;
+        try {
+            jsonMap  = mapper.readValue(response, Map.class);
+            jsonNode = mapper.convertValue(jsonMap, JsonNode.class);
+            objNode = (ObjectNode) jsonNode;
+        } catch (IOException ioEx) {
+            log.error(
+                "Failed to retrieve monitoring statistics from device {}",
+                deviceId
+            );
+            return monStats;
+        }
+
+        if (jsonMap == null) {
+            log.error(
+                "Failed to retrieve monitoring statistics from device {}",
+                deviceId
+            );
+            return monStats;
+        }
+
+        // Get the ID of the traffic class
+        String id = get(jsonNode, PARAM_ID);
+
+        // And verify that this is the traffic class we want to monitor
+        if (!id.equals(tcId.toString())) {
+            throw new RuntimeException(
+                "Failed to retrieve monitoring data for traffic class " + tcId +
+                ". Traffic class ID does not agree."
+            );
+        }
+
+        // Get a list of CPU statistics per core
+        Collection<CpuStatistics> cpuStats = parseCpuStatistics(deviceId, objNode);
+
+        // Get a list of port statistics
+        Collection<PortStatistics> nicStats = parseNicStatistics(deviceId, objNode);
+
+        // Get timing statistics
+        TimingStatistics timinsgStats = parseTimingStatistics(objNode);
+
+        // Ready to construct the grand object
+        DefaultMonitoringStatistics.Builder statsBuilder =
+            DefaultMonitoringStatistics.builder();
+
+        statsBuilder.setDeviceId(deviceId)
+                .setTimingStatistics(timinsgStats)
+                .setCpuStatistics(cpuStats)
+                .setNicStatistics(nicStats)
+                .build();
+
+        monStats = statsBuilder.build();
+
+        log.debug("Monitoring statistics: {}", monStats.toString());
+
+        return monStats;
+    }
+
+    /**
+     * Parse the input JSON object, looking for CPU-related
+     * statistics. Upon success, construct and return a list
+     * of CPU statistics objects.
+     *
+     * @param deviceId the device ID that sent the JSON object
+     * @param objNode input JSON node with CPU statistics information
+     * @return list of (per core) CpuStatistics
+     */
+    private Collection<CpuStatistics> parseCpuStatistics(
+            DeviceId deviceId, JsonNode objNode) {
+        Collection<CpuStatistics> cpuStats = Lists.newArrayList();
+
+        if (objNode == null) {
+            return cpuStats;
+        }
+
+        JsonNode cpuNode = objNode.path(PARAM_CPUS);
+
+        for (JsonNode cn : cpuNode) {
+            ObjectNode cpuObjNode = (ObjectNode) cn;
+
+            // CPU ID with its load and status
+            int   cpuId    = cpuObjNode.path(CPU_PARAM_ID).asInt();
+            float cpuLoad  = cpuObjNode.path(CPU_PARAM_LOAD).floatValue();
+            boolean isBusy = cpuObjNode.path(CPU_PARAM_STATUS).booleanValue();
+
+            // Incorporate these statistics into an object
+            DefaultCpuStatistics.Builder cpuBuilder =
+                DefaultCpuStatistics.builder();
+
+            cpuBuilder.setDeviceId(deviceId)
+                    .setId(cpuId)
+                    .setLoad(cpuLoad)
+                    .setIsBusy(isBusy)
+                    .build();
+
+            // We have statistics for this CPU core
+            cpuStats.add(cpuBuilder.build());
+        }
+
+        return cpuStats;
+    }
+
+    /**
+     * Parse the input JSON object, looking for NIC-related
+     * statistics. Upon success, construct and return a list
+     * of NIC statistics objects.
+     *
+     * @param deviceId the device ID that sent the JSON object
+     * @param objNode input JSON node with NIC statistics information
+     * @return list of (per port) PortStatistics
+     */
+    private Collection<PortStatistics> parseNicStatistics(
+            DeviceId deviceId, JsonNode objNode) {
+        Collection<PortStatistics> nicStats = Lists.newArrayList();
+
+        if (objNode == null) {
+            return nicStats;
+        }
+
+        JsonNode nicNode = objNode.path(PARAM_NICS);
+
+        for (JsonNode nn : nicNode) {
+            ObjectNode nicObjNode = (ObjectNode) nn;
+
+            // All the NIC attributes
+            String nicId  = get(nn, NIC_PARAM_ID);
+            int port = Integer.parseInt(nicId.replaceAll("\\D+", ""));
+
+            long rxCount   = nicObjNode.path(NIC_STATS_RX_COUNT).asLong();
+            long rxBytes   = nicObjNode.path(NIC_STATS_RX_BYTES).asLong();
+            long rxDropped = nicObjNode.path(NIC_STATS_RX_DROPS).asLong();
+            long rxErrors  = nicObjNode.path(NIC_STATS_RX_ERRORS).asLong();
+            long txCount   = nicObjNode.path(NIC_STATS_TX_COUNT).asLong();
+            long txBytes   = nicObjNode.path(NIC_STATS_TX_BYTES).asLong();
+            long txDropped = nicObjNode.path(NIC_STATS_TX_DROPS).asLong();
+            long txErrors  = nicObjNode.path(NIC_STATS_TX_ERRORS).asLong();
+
+            // Incorporate these statistics into an object
+            DefaultPortStatistics.Builder nicBuilder =
+                DefaultPortStatistics.builder();
+
+            nicBuilder.setDeviceId(deviceId)
+                    .setPort(port)
+                    .setPacketsReceived(rxCount)
+                    .setPacketsSent(txCount)
+                    .setBytesReceived(rxBytes)
+                    .setBytesSent(txBytes)
+                    .setPacketsRxDropped(rxDropped)
+                    .setPacketsRxErrors(rxErrors)
+                    .setPacketsTxDropped(txDropped)
+                    .setPacketsTxErrors(txErrors)
+                    .build();
+
+            // We have statistics for this NIC
+            nicStats.add(nicBuilder.build());
+        }
+
+        return nicStats;
+    }
+
+    /**
+     * Parse the input JSON object, looking for timing-related
+     * statistics. Upon success, construct and return a
+     * timing statistics object.
+     *
+     * @param objNode input JSON node with timing statistics information
+     * @return TimingStatistics object or null
+     */
+    private TimingStatistics parseTimingStatistics(JsonNode objNode) {
+        TimingStatistics timinsgStats = null;
+
+        if (objNode == null) {
+            return timinsgStats;
+        }
+
+        // Get timing statistics
+        JsonNode timingNode = objNode.path(PARAM_TIMING_STATS);
+        ObjectNode timingObjNode = (ObjectNode) timingNode;
+
+        // Time (ns) to parse the controller's deployment instruction
+        long parsingTime = timingObjNode.path(TIMING_PARAM_PARSE).asLong();
+        // Time (ns) to do the deployment
+        long launchingTime = timingObjNode.path(TIMING_PARAM_LAUNCH).asLong();
+        // Total time (ns)
+        long totalTime = parsingTime + launchingTime;
+
+        // Get autoscale timing statistics
+        JsonNode autoscaleTimingNode = objNode.path(PARAM_TIMING_AUTOSCALE);
+        ObjectNode autoscaleTimingObjNode = (ObjectNode) autoscaleTimingNode;
+
+        // Time (ns) to autoscale a server's load
+        long autoscaleTime = autoscaleTimingObjNode.path(
+            TIMING_PARAM_AUTOSCALE
+        ).asLong();
+
+        DefaultTimingStatistics.Builder timingBuilder =
+            DefaultTimingStatistics.builder();
+
+        timingBuilder.setParsingTime(parsingTime)
+                    .setLaunchingTime(launchingTime)
+                    .setAutoscaleTime(autoscaleTime)
+                    .build();
+
+        return timingBuilder.build();
+    }
+
+    /**
+     * Return a timing statistics object with zero counters.
+     * This is useful when constructing MonitoringStatistics
+     * objects that do not require timers.
+     *
+     * @return TimingStatistics object
+     */
+    private TimingStatistics getZeroTimingStatistics() {
+        DefaultTimingStatistics.Builder zeroTimingBuilder =
+            DefaultTimingStatistics.builder();
+
+        zeroTimingBuilder.setParsingTime(0)
+                         .setLaunchingTime(0)
+                         .setAutoscaleTime(0)
+                         .build();
+
+        return zeroTimingBuilder.build();
+    }
+
+}
