gt:                 throw new AssertionError();
context: /*
   * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.  Oracle designates this
   * particular file as subject to the "Classpath" exception as provided
   * by Oracle in the LICENSE file that accompanied this code.
   *
   * This code is distributed in the hope that it will be useful, but WITHOUT
   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   * version 2 for more details (a copy is included in the LICENSE file that
   * accompanied this code).
   *
   * You should have received a copy of the GNU General Public License version
   * 2 along with this work; if not, write to the Free Software Foundation,
   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   *
   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   * or visit www.oracle.com if you need additional information or have any
   * questions.
   */
  
  package com.sun.xml.internal.ws.fault;
  
  import com.sun.istack.internal.NotNull;
  import com.sun.istack.internal.Nullable;
  import com.sun.xml.internal.ws.api.SOAPVersion;
  import com.sun.xml.internal.ws.api.message.Message;
  import com.sun.xml.internal.ws.api.model.CheckedException;
  import com.sun.xml.internal.ws.api.model.ExceptionType;
  import com.sun.xml.internal.ws.encoding.soap.SOAP12Constants;
  import com.sun.xml.internal.ws.encoding.soap.SOAPConstants;
  import com.sun.xml.internal.ws.encoding.soap.SerializationException;
  import com.sun.xml.internal.ws.message.jaxb.JAXBMessage;
  import com.sun.xml.internal.ws.message.FaultMessage;
  import com.sun.xml.internal.ws.model.CheckedExceptionImpl;
  import com.sun.xml.internal.ws.model.JavaMethodImpl;
  import com.sun.xml.internal.ws.spi.db.XMLBridge;
  import com.sun.xml.internal.ws.util.DOMUtil;
  import com.sun.xml.internal.ws.util.StringUtils;
  import org.w3c.dom.Document;
  import org.w3c.dom.Element;
  import org.w3c.dom.Node;
  
  import javax.xml.bind.JAXBContext;
  import javax.xml.bind.JAXBException;
  import javax.xml.bind.annotation.XmlTransient;
  import javax.xml.namespace.QName;
  import javax.xml.soap.SOAPFault;
  import javax.xml.soap.Detail;
  import javax.xml.soap.DetailEntry;
  import javax.xml.transform.dom.DOMResult;
  import javax.xml.ws.ProtocolException;
  import javax.xml.ws.WebServiceException;
  import javax.xml.ws.soap.SOAPFaultException;
  import java.lang.reflect.Constructor;
  import java.lang.reflect.Field;
  import java.lang.reflect.Method;
  import java.util.Iterator;
  import java.util.Map;
  import java.util.logging.Level;
  import java.util.logging.Logger;
  
  /**
   * Base class that represents SOAP 1.1 or SOAP 1.2 fault. This class can be used by the invocation handlers to create
   * an Exception from a received messge.
   *
   * @author Vivek Pandey
   */
  public abstract class SOAPFaultBuilder {
  
      /**
       * Gives the {@link DetailType} for a Soap 1.1 or Soap 1.2 message that can be used to create either a checked exception or
       * a protocol specific exception
       */
      abstract DetailType getDetail();
  
      abstract void setDetail(DetailType detailType);
  
      public @XmlTransient @Nullable QName getFirstDetailEntryName() {
          DetailType dt = getDetail();
          if (dt != null) {
              Node entry = dt.getDetail(0);
              if (entry != null) {
                  return new QName(entry.getNamespaceURI(), entry.getLocalName());
              }
          }
          return null;
      }
  
      /**
       * gives the fault string that can be used to create an {@link Exception}
       */
      abstract String getFaultString();
  
      /**
       * This should be called from the client side to throw an {@link Exception} for a given soap mesage
       */
      public Throwable createException(Map<QName, CheckedExceptionImpl> exceptions) throws JAXBException {
          DetailType dt = getDetail();
          Node detail = null;
          if(dt != null)  detail = dt.getDetail(0);
  
          //return ProtocolException if the detail is not present or there is no checked exception
          if(detail == null || exceptions == null){
              // No soap detail, doesnt look like its a checked exception
              // throw a protocol exception
              return attachServerException(getProtocolException());
          }
  
          //check if the detail is a checked exception, if not throw a ProtocolException
          QName detailName = new QName(detail.getNamespaceURI(), detail.getLocalName());
          CheckedExceptionImpl ce = exceptions.get(detailName);
          if (ce == null) {
              //No Checked exception for the received detail QName, throw a SOAPFault exception
              return attachServerException(getProtocolException());
  
          }
  
          if (ce.getExceptionType().equals(ExceptionType.UserDefined)) {
              return attachServerException(createUserDefinedException(ce));
  
          }
          Class exceptionClass = ce.getExceptionClass();
          try {
              Constructor constructor = exceptionClass.getConstructor(String.class, (Class) ce.getDetailType().type);
              Exception exception = (Exception) constructor.newInstance(getFaultString(), getJAXBObject(detail, ce));
              return attachServerException(exception);
          } catch (Exception e) {
              throw new WebServiceException(e);
          }
      }
  
      /**
       * To be called to convert a  {@link ProtocolException} and faultcode for a given {@link SOAPVersion} in to a {@link Message}.
       *
       * @param soapVersion {@link SOAPVersion#SOAP_11} or {@link SOAPVersion#SOAP_12}
       * @param ex a ProtocolException
       * @param faultcode soap faultcode. Its ignored if the {@link ProtocolException} instance is {@link SOAPFaultException} and it has a
       * faultcode present in the underlying {@link SOAPFault}.
       * @return {@link Message} representing SOAP fault
       */
      public static @NotNull Message createSOAPFaultMessage(@NotNull SOAPVersion soapVersion, @NotNull ProtocolException ex, @Nullable QName faultcode){
          Object detail = getFaultDetail(null, ex);
          if(soapVersion == SOAPVersion.SOAP_12)
              return createSOAP12Fault(soapVersion, ex, detail, null, faultcode);
          return createSOAP11Fault(soapVersion, ex, detail, null, faultcode);
      }
  
      /**
       * To be called by the server runtime in the situations when there is an Exception that needs to be transformed in
       * to a soapenv:Fault payload.
       *
       * @param ceModel     {@link CheckedExceptionImpl} model that provides useful informations such as the detail tagname
       *                    and the Exception associated with it. Caller of this constructor should get the CheckedException
       *                    model by calling {@link JavaMethodImpl#getCheckedException(Class)}, where
       *                    Class is t.getClass().
       *                    <p>
       *                    If its null then this is not a checked exception  and in that case the soap fault will be
       *                    serialized only from the exception as described below.
       * @param ex          Exception that needs to be translated into soapenv:Fault, always non-null.
       *                    <ul>
       *                    <li>If t is instance of {@link SOAPFaultException} then its serilaized as protocol exception.
       *                    <li>If t.getCause() is instance of {@link SOAPFaultException} and t is a checked exception then
       *                    the soap fault detail is serilaized from t and the fault actor/string/role is taken from t.getCause().
       *                    </ul>
       * @param soapVersion non-null
       */
      public static Message createSOAPFaultMessage(SOAPVersion soapVersion, CheckedExceptionImpl ceModel, Throwable ex) {
          return createSOAPFaultMessage(soapVersion, ceModel, ex, null);
      }
  
      /**
       * Create the Message with the specified faultCode
       *
       * @see #createSOAPFaultMessage(SOAPVersion, CheckedExceptionImpl, Throwable)
       */
      public static Message createSOAPFaultMessage(SOAPVersion soapVersion, CheckedExceptionImpl ceModel, Throwable ex, QName faultCode) {
          Object detail = getFaultDetail(ceModel, ex);
          if(soapVersion == SOAPVersion.SOAP_12)
              return createSOAP12Fault(soapVersion, ex, detail, ceModel, faultCode);
          return createSOAP11Fault(soapVersion, ex, detail, ceModel, faultCode);
      }
  
      /**
       * Server runtime will call this when there is some internal error not resulting from an exception.
       *
       * @param soapVersion {@link SOAPVersion#SOAP_11} or {@link SOAPVersion#SOAP_12}
       * @param faultString must be non-null
       * @param faultCode   For SOAP 1.1, it must be one of
       *                    <ul>
       *                    <li>{@link SOAPVersion#faultCodeClient}
       *                    <li>{@link SOAPVersion#faultCodeServer}
       *                    <li>{@link SOAPConstants#FAULT_CODE_MUST_UNDERSTAND}
       *                    <li>{@link SOAPConstants#FAULT_CODE_VERSION_MISMATCH}
       *                    </ul>
       *
       *                    For SOAP 1.2
       *                    <ul>
       *                    <li>{@link SOAPVersion#faultCodeClient}
       *                    <li>{@link SOAPVersion#faultCodeServer}
       *                    <li>{@link SOAP12Constants#FAULT_CODE_MUST_UNDERSTAND}
       *                    <li>{@link SOAP12Constants#FAULT_CODE_VERSION_MISMATCH}
       *                    <li>{@link SOAP12Constants#FAULT_CODE_DATA_ENCODING_UNKNOWN}
       *                    </ul>
       * @return non-null {@link Message}
       */
      public static Message createSOAPFaultMessage(SOAPVersion soapVersion, String faultString, QName faultCode) {
          if (faultCode == null)
              faultCode = getDefaultFaultCode(soapVersion);
          return createSOAPFaultMessage(soapVersion, faultString, faultCode, null);
      }
  
      public static Message createSOAPFaultMessage(SOAPVersion soapVersion, SOAPFault fault) {
          switch (soapVersion) {
              case SOAP_11:
                  return JAXBMessage.create(JAXB_CONTEXT, new SOAP11Fault(fault), soapVersion);
              case SOAP_12:
                  return JAXBMessage.create(JAXB_CONTEXT, new SOAP12Fault(fault), soapVersion);
              default:
  