/**
   * Execute refresh method. This method is called every time a binding item is refreshed and the
   * corresponding node should be sent a message.
   *
   * @param provider the {@link ZWaveBindingProvider} that provides the item
   * @param itemName the name of the item to poll.
   * @param forceRefresh indicates that a polling refresh should be forced.
   */
  @SuppressWarnings("unchecked")
  public void executeRefresh(ZWaveBindingProvider provider, String itemName, boolean forceRefresh) {
    ZWaveBindingConfig bindingConfiguration = provider.getZwaveBindingConfig(itemName);
    ZWaveCommandClass commandClass;
    String commandClassName = bindingConfiguration.getArguments().get("command");

    // this binding is configured not to poll.
    if (!forceRefresh
        && bindingConfiguration.getRefreshInterval() != null
        && 0 == bindingConfiguration.getRefreshInterval()) return;

    ZWaveNode node = this.controller.getNode(bindingConfiguration.getNodeId());

    // ignore nodes that are not initialized or dead.
    if (node == null) return;

    if (commandClassName != null) {

      // this is a report item, handle it with the report info converter.
      if (commandClassName.equalsIgnoreCase("info")) {
        infoConverter.executeRefresh(
            provider.getItem(itemName),
            node,
            bindingConfiguration.getEndpoint(),
            bindingConfiguration.getArguments());
        return;
      }

      // ignore nodes that are not initialized or dead.
      if (node.getNodeStage() != NodeStage.DONE) return;

      commandClass =
          node.resolveCommandClass(
              CommandClass.getCommandClass(commandClassName), bindingConfiguration.getEndpoint());

      if (commandClass == null) {
        logger.warn(
            "No command class found for item = {}, command class name = {}, ignoring execute refresh.",
            itemName,
            commandClassName);
        return;
      }
    } else {
      commandClass =
          resolveConverter(provider.getItem(itemName), node, bindingConfiguration.getEndpoint());
    }

    if (commandClass == null) {
      logger.warn("No converter found for item = {}, ignoring execute refresh.", itemName);
      return;
    }

    ZWaveCommandClassConverter<ZWaveCommandClass> converter =
        (ZWaveCommandClassConverter<ZWaveCommandClass>)
            getConverter(commandClass.getCommandClass());

    if (converter == null) {
      logger.warn("No converter found for item = {}, ignoring execute refresh.", itemName);
      return;
    }

    if (bindingConfiguration.getRefreshInterval() == null) {
      bindingConfiguration.setRefreshInterval(converter.getRefreshInterval());

      // this binding is configured not to poll.
      if (!forceRefresh && 0 == bindingConfiguration.getRefreshInterval()) return;
    }

    // not enough time has passed to refresh the item.
    if (!forceRefresh
        && bindingConfiguration.getLastRefreshed() != null
        && (bindingConfiguration.getLastRefreshed().getTime()
                + (bindingConfiguration.getRefreshInterval() * 1000)
            > Calendar.getInstance().getTimeInMillis())) return;

    bindingConfiguration.setLastRefreshed(Calendar.getInstance().getTime());
    converter.executeRefresh(
        node,
        commandClass,
        bindingConfiguration.getEndpoint(),
        bindingConfiguration.getArguments());
  }