gt:             if (configurationParameter.getKey().startsWith("ntp")) {
context: /**
   * Copyright (c) 2010-2018 by the respective copyright holders.
   *
   * All rights reserved. This program and the accompanying materials
   * are made available under the terms of the Eclipse Public License v1.0
   * which accompanies this distribution, and is available at
   * http://www.eclipse.org/legal/epl-v10.html
   */
  package org.openhab.binding.max.internal.handler;
  
  import static org.eclipse.smarthome.core.library.unit.SIUnits.CELSIUS;
  import static org.openhab.binding.max.internal.MaxBindingConstants.*;
  
  import java.io.BufferedReader;
  import java.io.IOException;
  import java.io.InputStreamReader;
  import java.io.OutputStreamWriter;
  import java.math.BigDecimal;
  import java.math.RoundingMode;
  import java.net.ConnectException;
  import java.net.Socket;
  import java.net.SocketException;
  import java.net.UnknownHostException;
  import java.nio.charset.StandardCharsets;
  import java.util.ArrayList;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Map;
  import java.util.Map.Entry;
  import java.util.Set;
  import java.util.concurrent.ArrayBlockingQueue;
  import java.util.concurrent.BlockingQueue;
  import java.util.concurrent.CopyOnWriteArraySet;
  import java.util.concurrent.ScheduledFuture;
  import java.util.concurrent.TimeUnit;
  import java.util.concurrent.locks.Condition;
  import java.util.concurrent.locks.ReentrantLock;
  
  import javax.measure.quantity.Temperature;
  
  import org.eclipse.smarthome.config.core.Configuration;
  import org.eclipse.smarthome.core.library.types.DecimalType;
  import org.eclipse.smarthome.core.library.types.OnOffType;
  import org.eclipse.smarthome.core.library.types.QuantityType;
  import org.eclipse.smarthome.core.library.types.StringType;
  import org.eclipse.smarthome.core.thing.Bridge;
  import org.eclipse.smarthome.core.thing.ChannelUID;
  import org.eclipse.smarthome.core.thing.Thing;
  import org.eclipse.smarthome.core.thing.ThingStatus;
  import org.eclipse.smarthome.core.thing.ThingStatusDetail;
  import org.eclipse.smarthome.core.thing.binding.BaseBridgeHandler;
  import org.eclipse.smarthome.core.thing.binding.ThingHandler;
  import org.eclipse.smarthome.core.types.Command;
  import org.eclipse.smarthome.core.types.RefreshType;
  import org.openhab.binding.max.internal.MaxBindingConstants;
  import org.openhab.binding.max.internal.command.ACommand;
  import org.openhab.binding.max.internal.command.CCommand;
  import org.openhab.binding.max.internal.command.CubeCommand;
  import org.openhab.binding.max.internal.command.FCommand;
  import org.openhab.binding.max.internal.command.LCommand;
  import org.openhab.binding.max.internal.command.MCommand;
  import org.openhab.binding.max.internal.command.NCommand;
  import org.openhab.binding.max.internal.command.QCommand;
  import org.openhab.binding.max.internal.command.SCommand;
  import org.openhab.binding.max.internal.command.TCommand;
  import org.openhab.binding.max.internal.command.UdpCubeCommand;
  import org.openhab.binding.max.internal.config.MaxCubeBridgeConfiguration;
  import org.openhab.binding.max.internal.device.Device;
  import org.openhab.binding.max.internal.device.DeviceConfiguration;
  import org.openhab.binding.max.internal.device.DeviceInformation;
  import org.openhab.binding.max.internal.device.DeviceType;
  import org.openhab.binding.max.internal.device.HeatingThermostat;
  import org.openhab.binding.max.internal.device.RoomInformation;
  import org.openhab.binding.max.internal.device.ThermostatModeType;
  import org.openhab.binding.max.internal.exceptions.UnprocessableMessageException;
  import org.openhab.binding.max.internal.message.CMessage;
  import org.openhab.binding.max.internal.message.FMessage;
  import org.openhab.binding.max.internal.message.HMessage;
  import org.openhab.binding.max.internal.message.LMessage;
  import org.openhab.binding.max.internal.message.MMessage;
  import org.openhab.binding.max.internal.message.Message;
  import org.openhab.binding.max.internal.message.MessageProcessor;
  import org.openhab.binding.max.internal.message.NMessage;
  import org.openhab.binding.max.internal.message.SMessage;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  /**
   * {@link MaxCubeBridgeHandler} is the handler for a MAX! Cube and connects it
   * to the framework. All {@link MaxDevicesHandler}s use the
   * {@link MaxCubeBridgeHandler} to execute the actual commands.
   *
   * @author Andreas Heil (info@aheil.de) - Initial contribution
   * @author Marcel Verpaalen - Initial contribution OH2 version
   * @author Bernd Michael Helm (bernd.helm at helmundwalter.de) - Exclusive mode
   */
  public class MaxCubeBridgeHandler extends BaseBridgeHandler {
      private final Logger logger = LoggerFactory.getLogger(MaxCubeBridgeHandler.class);
  
      /** timeout on network connection **/
      private static final int NETWORK_TIMEOUT = 10000;
  
      private final List<Device> devices = new ArrayList<>();
      private List<RoomInformation> rooms;
      private final Set<String> lastActiveDevices = new HashSet<>();
  
      /** MAX! Thermostat default off temperature */
      private static final double DEFAULT_OFF_TEMPERATURE = 4.5;
  
      /** MAX! Thermostat default on temperature */
      private static final double DEFAULT_ON_TEMPERATURE = 30.5;
  
      private final List<DeviceConfiguration> configurations = new ArrayList<>();
  
      /** maximum queue size that we're allowing */
      private static final int MAX_COMMANDS = 50;
      private final BlockingQueue<SendCommand> commandQueue = new ArrayBlockingQueue<>(MAX_COMMANDS);
  
      private SendCommand lastCommandId;
  
      private long refreshInterval = 30;
      private String ipAddress;
      private int port;
      private boolean exclusive;
      private int maxRequestsPerConnection;
      private String ntpServer1;
      private String ntpServer2;
      private int requestCount;
      private boolean propertiesSet;
      private boolean roomPropertiesSet;
  
      private final MessageProcessor messageProcessor = new MessageProcessor();
  
      private static final int MAX_DUTY_CYCLE = 80;
      private final ReentrantLock dutyCycleLock = new ReentrantLock();
      private final Condition excessDutyCycle = dutyCycleLock.newCondition();
  
      /**
       * Duty cycle of the cube
       */
      private int dutyCycle;
  
      /**
       * The available memory slots of the cube
       */
      private int freeMemorySlots;
  
      /**
       * connection socket and reader/writer for execute method
       */
      private Socket socket;
      private BufferedReader reader;
      private OutputStreamWriter writer;
  
      private boolean previousOnline;
  
      private final Set<DeviceStatusListener> deviceStatusListeners = new CopyOnWriteArraySet<>();
  
      private ScheduledFuture<?> pollingJob;
  
      private Thread queueConsumerThread;
  
      public MaxCubeBridgeHandler(Bridge br) {
          super(br);
      }
  
      @Override
      public void handleCommand(ChannelUID channelUID, Command command) {
          if (command instanceof RefreshType) {
              logger.debug("Refresh command received.");
              refreshData();
          } else {
              logger.warn("No bridge commands defined. Cannot process '{}'.", command);
          }
      }
  
      @Override
      public void dispose() {
          logger.debug("Handler disposed.");
          try {
              stopAutomaticRefresh();
          } catch (InterruptedException e) {
              logger.error("Could not stop automatic refresh", e);
              Thread.currentThread().interrupt();
          }
          clearDeviceList();
  
          socketClose();
          super.dispose();
      }
  
      @Override
      public void initialize() {
          logger.debug("Initializing MAX! Cube bridge handler.");
  
          MaxCubeBridgeConfiguration configuration = getConfigAs(MaxCubeBridgeConfiguration.class);
          port = configuration.port;
          ipAddress = configuration.ipAddress;
          refreshInterval = configuration.refreshInterval;
          exclusive = configuration.exclusive;
          maxRequestsPerConnection = configuration.maxRequestsPerConnection;
          ntpServer1 = configuration.ntpServer1;
          ntpServer2 = configuration.ntpServer2;
          logger.debug("Cube IP         {}.", ipAddress);
          logger.debug("Port            {}.", port);
          logger.debug("RefreshInterval {}.", refreshInterval);
          logger.debug("Exclusive mode  {}.", exclusive);
          logger.debug("Max Requests    {}.", maxRequestsPerConnection);
  
          previousOnline = true; // To trigger offline in case no connection @ startup
  
          startAutomaticRefresh();
      }
  
      @Override
      public void handleConfigurationUpdate(Map<String, Object> configurationParameters) {
          boolean refresh = true;
          logger.debug("MAX! Cube {}: Configuration update received", getThing().getThingTypeUID());
  
          Configuration configuration = editConfiguration();
          for (Entry<String, Object> configurationParameter : configurationParameters.entrySet()) {
              logger.debug("MAX! Cube {}: Configuration update {} to {}", getThing().getThingTypeUID(),
                      configurationParameter.getKey(), configurationParameter.getValue());
  