text: var Service, BluetoothCharacteristic;
  var Chalk = require('chalk');
  
  module.exports = function (service, bluetoothCharacteristic) {
    Service = service;
    BluetoothCharacteristic = bluetoothCharacteristic;
  
    return BluetoothService;
  };
  
  
  function BluetoothService(log, config, prefix) {
    this.log = log;
  
    if (!config.name) {
      throw new Error("Missing mandatory config 'name'");
    }
    this.name = config.name;
    this.prefix = prefix + " " + Chalk.magenta("[" + this.name + "]");
  
    if (!config.type) {
      throw new Error(this.prefix + " Missing mandatory config 'type'");
    }
    this.type = config.type;
    if (!Service[this.type]) {
      throw new Error(this.prefix + " Service type '" + this.type + "' is not defined. " +
                      "See 'HAP-NodeJS/lib/gen/HomeKitType.js' for options.")
    }
    this.class = Service[this.type]; // For example - Service.Lightbulb
  
    if (!config.UUID) {
      throw new Error(this.prefix + " Missing mandatory config 'UUID'");
    }
    this.UUID = config.UUID;
  
    if (!config.characteristics || !(config.characteristics instanceof Array)) {
      throw new Error(this.prefix + " Missing mandatory config 'characteristics'");
    }
  
    this.log.debug(this.prefix, "Initialized | Service." + this.type + " (" + this.UUID + ")");
    this.bluetoothCharacteristics = {};
    for (var characteristicConfig of config.characteristics) {
      var characteristicUUID = trimUUID(characteristicConfig.UUID);
      this.bluetoothCharacteristics[characteristicUUID] =
          new BluetoothCharacteristic(this.log, characteristicConfig, this.prefix);
    }
  
    this.homebridgeService = null;
    this.nobleService = null;
  }
  
  
  BluetoothService.prototype.connect = function (nobleService, homebridgeService) {
    this.log.info(this.prefix, "Connected");
    this.log.debug(this.prefix, "Service." + this.type + " (" + this.UUID + ")");
    this.homebridgeService = homebridgeService;
  
    this.nobleService = nobleService;
    this.nobleService.discoverCharacteristics([], this.discoverCharacteristics.bind(this));
  };
  
  
  BluetoothService.prototype.discoverCharacteristics = function (error, nobleCharacteristics) {
    if (error) {
      this.log.error(this.prefix, "Discover characteristics failed | " + error);
      return;
    }
    if (nobleCharacteristics.length == 0) {
      this.log.warn(this.prefix, "No characteristics discovered");
      return;
    }
  
    for (var nobleCharacteristic of nobleCharacteristics) {
      var characteristicUUID = trimUUID(nobleCharacteristic.uuid);
      var bluetoothCharacteristic = this.bluetoothCharacteristics[characteristicUUID];
      if (!bluetoothCharacteristic) {
        this.log.debug(this.prefix, "Ignored | Characteristic (" + nobleCharacteristic.uuid + ")");
        continue;
      }
  
      var homebridgeCharacteristic =
          this.homebridgeService.getCharacteristic(bluetoothCharacteristic.class);
      bluetoothCharacteristic.connect(nobleCharacteristic, homebridgeCharacteristic);
    }
  };
  
  
  BluetoothService.prototype.disconnect = function () {
    for (var characteristicUUID in this.bluetoothCharacteristics) {
      this.bluetoothCharacteristics[characteristicUUID].disconnect();
    }
    if (this.nobleCharacteristic && this.homebridgeCharacteristic) {
      this.homebridgeService = null;
      this.nobleService = null;
      this.log.info(this.prefix, "Disconnected");
    }
  };
  
  
  function trimUUID(uuid) {
    return uuid.toLowerCase().replace(/:/g, "").replace(/-/g, "");
  }
  