/**
   * Handles a specific STUN error <tt>Response</tt> with error code "401 Unauthorized" to a
   * specific STUN <tt>Request</tt>.
   *
   * @param response the received STUN error <tt>Response</tt> with error code "401 Unauthorized"
   *     which is to be handled
   * @param request the STUN <tt>Request</tt> to which <tt>response</tt> responds
   * @param transactionID the <tt>TransactionID</tt> of <tt>response</tt> and <tt>request</tt>
   *     because <tt>response</tt> and <tt>request</tt> only have it as a <tt>byte</tt> array and
   *     <tt>TransactionID</tt> is required for the <tt>applicationData</tt> property value
   * @return <tt>true</tt> if the specified STUN error <tt>response</tt> was successfully handled;
   *     <tt>false</tt>, otherwise
   * @throws StunException if anything goes wrong while handling the specified "401 Unauthorized"
   *     error <tt>response</tt>
   */
  private boolean processUnauthorized(
      Response response, Request request, TransactionID transactionID) throws StunException {
    /*
     * If the response is a challenge, retry the request with a new
     * transaction.
     */
    boolean challenge = true;

    /*
     * The client SHOULD omit the USERNAME, MESSAGE-INTEGRITY, REALM, and
     * NONCE attributes from the "First Request".
     */
    if (request.getAttributeCount() > 0) {
      char[] excludedRequestAttributeTypes =
          new char[] {
            Attribute.USERNAME, Attribute.MESSAGE_INTEGRITY, Attribute.REALM, Attribute.NONCE
          };

      for (char excludedRequestAttributeType : excludedRequestAttributeTypes) {
        if (request.containsAttribute(excludedRequestAttributeType)) {
          challenge = false;
          break;
        }
      }
    }

    return (challenge && processChallenge(response, request, transactionID));
  }
  /**
   * Handles a specific STUN error <tt>Response</tt> with error code "438 Stale Nonce" to a specific
   * STUN <tt>Request</tt>.
   *
   * @param response the received STUN error <tt>Response</tt> with error code "438 Stale Nonce"
   *     which is to be handled
   * @param request the STUN <tt>Request</tt> to which <tt>response</tt> responds
   * @param transactionID the <tt>TransactionID</tt> of <tt>response</tt> and <tt>request</tt>
   *     because <tt>response</tt> and <tt>request</tt> only have it as a <tt>byte</tt> array and
   *     <tt>TransactionID</tt> is required for the <tt>applicationData</tt> property value
   * @return <tt>true</tt> if the specified STUN error <tt>response</tt> was successfully handled;
   *     <tt>false</tt>, otherwise
   * @throws StunException if anything goes wrong while handling the specified "438 Stale Nonce"
   *     error <tt>response</tt>
   */
  private boolean processStaleNonce(Response response, Request request, TransactionID transactionID)
      throws StunException {
    /*
     * The request MUST contain USERNAME, REALM, NONCE and MESSAGE-INTEGRITY
     * attributes.
     */
    boolean challenge;

    if (request.getAttributeCount() > 0) {
      char[] includedRequestAttributeTypes =
          new char[] {
            Attribute.USERNAME, Attribute.REALM, Attribute.NONCE, Attribute.MESSAGE_INTEGRITY
          };
      challenge = true;

      for (char includedRequestAttributeType : includedRequestAttributeTypes) {
        if (!request.containsAttribute(includedRequestAttributeType)) {
          challenge = false;
          break;
        }
      }
    } else challenge = false;

    return (challenge && processChallenge(response, request, transactionID));
  }