/*
   *  Call this on cookies that were not set**, or on cookies whose inception
   *  date is newer than the current best cookie.  If a cookie is being set
   *  to the value of another existing cookie, there may be more than one
   *  cookie type with the identical EXISTING best value.  We just pick the
   *  first match in the order that the CookeType enumeration is declared.
   *
   *  ** If the cookie was not previously set, there may not be another
   *     EXISTING cookie to override it's value.  In this case, we set the
   *     target's state to NEW.
   */
  private void setHowCookieWasRestoredOrReplaced(CookieType targetType, boolean isReplacement) {
    CookieStates states = getCookieStates();

    if (states.get(targetType) == NOT_SUPPORTED) {
      return;
    }

    CookieState targetState = NEW;

    for (CookieType otherType : CookieType.values()) {
      if (otherType == targetType) {
        continue;
      }

      //  If a cookie was replaced by it's own ancestor, we want to treat it the same as EXISTING.
      CookieState otherState = getCookieStates().get(otherType);
      CookieState replacedFromStateForOtherType = replacedFromOlderState(otherType);
      if (otherState == EXISTING || otherState == replacedFromStateForOtherType) {
        targetState =
            (isReplacement) ? replacedFromStateForOtherType : restoredFromState(otherType);
        break;
      }
    }

    states.set(targetType, targetState);
  }
  private void cascadeNewBestCookie(CookieType newBestCookieType) {
    CookieStates states = getCookieStates();
    CookieState restoredFromState = restoredFromState(newBestCookieType);
    CookieState replacedFromState = replacedFromOlderState(newBestCookieType);

    // Terminology:
    //   restored:  means the cookie had no valid previous value
    //   replaced:  means the cookie had a valid previous value that was replaced
    //

    for (CookieType otherType : CookieType.values()) {

      CookieState otherState = states.get(otherType);

      if (otherType == newBestCookieType || otherState == null) {
        continue;
      }

      if (otherType == ETAG && otherState != RESET) {
        states.setEtagState(LINKED_BUT_NOT_SYNCED);
        continue;
      }

      switch (otherState) {
        case EXISTING:
        case REPLACED_BY_OLDER_SILVERLIGHT_COOKIE:
        case REPLACED_BY_OLDER_FLASH_COOKIE:
        case REPLACED_BY_OLDER_WEB_STORAGE_COOKIE:
        case REPLACED_BY_OLDER_PLAIN_COOKIE:
        case REPLACED_BY_OLDER_ETAG_COOKIE:
          states.set(otherType, replacedFromState);
          break;
        case NEW:
        case RESTORED_FROM_SILVERLIGHT_COOKIE:
        case RESTORED_FROM_FLASH_COOKIE:
        case RESTORED_FROM_WEB_STORAGE_COOKIE:
        case RESTORED_FROM_PLAIN_COOKIE:
        case RESTORED_FROM_ETAG_COOKIE:
          states.set(otherType, restoredFromState);
          break;
      }
    }
  }