/// <inheritdoc />
        public override IDeviceHandler CreateHandler(ISnmpLowerLayer lowerLayer, IQuerierOptions options)
        {
            string osVersionString = null;

            // try #1: In IEEE SNMP tree
            try
            {
                osVersionString = lowerLayer.QueryAsString(OsVersionOid, "MikroTik RouterOS Version String #1");
            }
            catch (SnmpException ex)
            {
                this.CollectException("MtikSnmp: Getting version string", ex);
                osVersionString = null;
            }
            catch (HamnetSnmpException ex)
            {
                this.CollectException("MtikSnmp: Getting version string", ex);
                osVersionString = null;
            }

            // try #2: Withing MikroTik enterprise tree
            if (string.IsNullOrWhiteSpace(osVersionString))
            {
                osVersionString = lowerLayer.QueryAsString(OsVersionOid2, "MikroTik RouterOS Version String #2");
            }

            // Example: "RouterOS 6.45.3 (stable) on RB711-5Hn-MMCX"
            Match match = OsVersionExtractionRegex.Match(osVersionString);

            SemanticVersion osVersion = match.Success ? match.Groups[1].Value.ToSemanticVersion() : null;

            var model = lowerLayer.SystemData.Description.Replace(RouterOsDetectionString, string.Empty).Trim();

            log.Info($"Detected device '{lowerLayer.Address}' as MikroTik '{model}' v '{osVersion}'");

            DeviceVersion            deviceVersion;
            IDeviceSpecificOidLookup oidTable = this.ObtainOidTable(model.Trim(), osVersion, out deviceVersion, lowerLayer.Address);

            if (string.IsNullOrWhiteSpace(deviceVersion.HandlerClassName))
            {
                try
                {
                    return(new MikrotikSnmpDeviceHandler(lowerLayer, oidTable, osVersion, model, options));
                }
                catch (Exception ex)
                {
                    this.CollectException("MtikSnmp: OID table lookup", ex);

                    // we want to catch and nest the exception here as the APIs involved are not able to append the infomration for which
                    // device (i.e. IP address) the exception is for
                    throw new HamnetSnmpException($"Failed to create MikroTik handler for device '{lowerLayer.Address}': {ex.Message}", ex, lowerLayer.Address?.ToString());
                }
            }
            else
            {
                return(this.GetHandlerViaReflection(deviceVersion.HandlerClassName, lowerLayer, oidTable, osVersion, model, options));
            }
        }