gt:             if (itemName.equals(state.items[i])) {
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.yamahareceiver.internal.protocol.xml;
  
  import java.io.IOException;
  import java.lang.ref.WeakReference;
  
  import org.openhab.binding.yamahareceiver.YamahaReceiverBindingConstants;
  import org.openhab.binding.yamahareceiver.internal.protocol.AbstractConnection;
  import org.openhab.binding.yamahareceiver.internal.protocol.InputWithNavigationControl;
  import org.openhab.binding.yamahareceiver.internal.protocol.ReceivedMessageParseException;
  import org.openhab.binding.yamahareceiver.internal.state.NavigationControlState;
  import org.openhab.binding.yamahareceiver.internal.state.NavigationControlStateListener;
  import org.w3c.dom.Document;
  import org.w3c.dom.Node;
  
  /**
   * This class implements the Yamaha Receiver protocol related to navigation functionally. USB, NET_RADIO, IPOD and
   * other inputs are using the same way of navigating through menus. A menu on Yamaha AVRs
   * is hierarchically organised. Entries are divided into pages with 8 elements per page.
   *
   * The XML nodes <List_Control> and <List_Info> are used.
   *
   * In contrast to other protocol classes an object of this type will store state information,
   * because it caches the received XML information of the updateNavigationState(). This may change
   * in the future.
   *
   * Example:
   *
   * NavigationControl menu = new NavigationControl("NET_RADIO", comObject);
   * menu.goToPath(menuDir);
   * menu.selectItem(stationName);
   *
   * @author David Graeff - Completely refactored class
   * @author Dennis Frommknecht - Initial idea and implementaton
   * @author Tomasz Maruszak - Refactor
   */
  public class InputWithNavigationControlXML implements InputWithNavigationControl {
      protected final WeakReference<AbstractConnection> comReference;
  
      protected final String inputID;
  
      public static final int MAX_PER_PAGE = 8;
      private boolean useAlternativeBackToHomeCmd = false;
  
      private NavigationControlState state;
      private NavigationControlStateListener observer;
  
      /**
       * Create a NavigationControl object for altering menu positions and requesting current menu information.
       *
       * @param state We need the current navigation state, because most navigation commands are relative commands and we
       *            offer API with absolute values.
       * @param inputID The input ID like USB or NET_RADIO.
       * @param com The Yamaha communication object to send http requests.
       */
      public InputWithNavigationControlXML(NavigationControlState state, String inputID, AbstractConnection com,
              NavigationControlStateListener observer) {
          this.state = state;
          this.comReference = new WeakReference<>(com);
          this.inputID = inputID;
          this.observer = observer;
      }
  
      /**
       * Wraps the XML message with the inputID tags. Example with inputID=NET_RADIO:
       * <NETRADIO>message</NETRADIO>.
       *
       * @param message XML message
       * @return
       */
      private String wrInput(String message) {
          return "<" + inputID + ">" + message + "</" + inputID + ">";
      }
  
      /**
       * Sends a cursor command to Yamaha.
       * @param command
       * @throws IOException
       * @throws ReceivedMessageParseException
       */
      private void navigateCursor(String command) throws IOException, ReceivedMessageParseException {
          comReference.get().send(wrInput("<List_Control><Cursor>" + command + "</Cursor></List_Control>"));
          update();
      }
  
      /**
       * Navigate back
       *
       * @throws Exception
       */
      @Override
      public void goBack() throws IOException, ReceivedMessageParseException {
          navigateCursor("Back");
      }
  
  
      /**
       * Navigate up
       *
       * @throws Exception
       */
      @Override
      public void goUp() throws IOException, ReceivedMessageParseException {
          navigateCursor("Up");
      }
  
      /**
       * Navigate down
       *
       * @throws Exception
       */
      @Override
      public void goDown() throws IOException, ReceivedMessageParseException {
          navigateCursor("Down");
      }
  
      /**
       * Navigate left. Not for all zones or functions available.
       *
       * @throws Exception
       */
      @Override
      public void goLeft() throws IOException, ReceivedMessageParseException {
          navigateCursor("Left");
      }
  
      /**
       * Navigate right. Not for all zones or functions available.
       *
       * @throws Exception
       */
      @Override
      public void goRight() throws IOException, ReceivedMessageParseException {
          navigateCursor("Right");
      }
  
      /**
       * Select current item. Not for all zones or functions available.
       *
       * @throws Exception
       */
      @Override
      public void selectCurrentItem() throws IOException, ReceivedMessageParseException {
          navigateCursor("Select");
      }
  
      /**
       * Navigate to root menu
       *
       * @throws Exception
       */
      @Override
      public boolean goToRoot() throws IOException, ReceivedMessageParseException {
          if (useAlternativeBackToHomeCmd) {
              navigateCursor("Return to Home");
              if (state.menuLayer > 0) {
                  observer.navigationError("Both going back to root commands failed for your receiver!");
                  return false;
              }
          } else {
              navigateCursor("Back to Home");
              if (state.menuLayer > 0) {
                  observer.navigationError("The going back to root command failed for your receiver. Trying to use a different command.");
                  useAlternativeBackToHomeCmd = true;
                  return goToRoot();
              }
          }
          return true;
      }
  
      @Override
      public void goToPage(int page) throws IOException, ReceivedMessageParseException {
          int line = (page - 1) * 8 + 1;
          comReference.get().send(wrInput("<List_Control><Jump_Line>" + line + "</Jump_Line></List_Control>"));
          update();
      }
  
      @Override
      public void selectItemFullPath(String fullPath) throws IOException, ReceivedMessageParseException {
          update();
  
          if (state.menuName == null) {
              return;
          }
  
          String[] pathArr = fullPath.split("/");
  
          // Just a relative menu item.
          if (pathArr.length < 2) {
              if (!selectItem(pathArr[0])) {
                  observer.navigationError("Item '" + pathArr[0] + "' doesn't exist in menu " + state.menuName);
              }
              return;
          }
  
          // Full path info not available, so guess from last path element and number of path elements
          String selectMenuName = pathArr[pathArr.length - 2];
          String selectItemName = pathArr[pathArr.length - 1];
          int selectMenuLevel = pathArr.length - 1;
  
          boolean sameMenu = state.menuName.equals(selectMenuName) && state.menuLayer == selectMenuLevel;
  
          if (sameMenu) {
              if (!selectItem(selectItemName)) {
                  observer.navigationError("Item '" + selectItemName + "' doesn't exist in menu " + state.menuName
                          + " at level " + String.valueOf(state.menuLayer) + ". Available options are: "
                          + state.getAllItemLabels());
              }
              return;
          }
  
          if (state.menuLayer > 0) {
              if (!goToRoot()) {
                  return;
              }
          }
  
          for (String pathElement : pathArr) {
              if (!selectItem(pathElement)) {
                  observer.navigationError("Item '" + pathElement + "' doesn't exist in menu " + state.menuName
                          + " at level " + String.valueOf(state.menuLayer) + ". Available options are: "
                          + state.getAllItemLabels());
                  return;
              }
          }
      }
  
      /**
       * Finds an item on the current page. A page contains up to 8 items.
       * Operates on a cached XML node! Call refreshMenuState for up-to-date information.
       *
       * @return Return the item index [1,8] or -1 if not found.
       */
      private int findItemOnCurrentPage(String itemName) {
          for (int i = 0; i < MAX_PER_PAGE; i++) {
  