/**
     * Add a new state to the state machine. Bottom up addition of states is allowed but the same
     * state may only exist in one hierarchy.
     *
     * @param state the state to add
     * @param parent the parent of state
     * @return stateInfo for this state
     */
    private final StateInfo addState(State state, State parent) {
      if (mDbg) {
        Log.d(
            TAG,
            "addStateInternal: E state="
                + state.getName()
                + ",parent="
                + ((parent == null) ? "" : parent.getName()));
      }
      StateInfo parentStateInfo = null;
      if (parent != null) {
        parentStateInfo = mStateInfo.get(parent);
        if (parentStateInfo == null) {
          // Recursively add our parent as it's not been added yet.
          parentStateInfo = addState(parent, null);
        }
      }
      StateInfo stateInfo = mStateInfo.get(state);
      if (stateInfo == null) {
        stateInfo = new StateInfo();
        mStateInfo.put(state, stateInfo);
      }

      // Validate that we aren't adding the same state in two different hierarchies.
      if ((stateInfo.parentStateInfo != null) && (stateInfo.parentStateInfo != parentStateInfo)) {
        throw new RuntimeException("state already added");
      }
      stateInfo.state = state;
      stateInfo.parentStateInfo = parentStateInfo;
      stateInfo.active = false;
      if (mDbg) Log.d(TAG, "addStateInternal: X stateInfo: " + stateInfo);
      return stateInfo;
    }