@Override
  public void begin(MessagePartInfo part) {
    Class<?> clazz = part.getTypeClass();
    if (clazz == null) {
      return;
    }

    if (Exception.class.isAssignableFrom(clazz)) {
      // exceptions are handled special, make sure we mark it
      part.setProperty(JAXBDataBinding.class.getName() + ".CUSTOM_EXCEPTION", Boolean.TRUE);
    }
    boolean isFromWrapper = part.getMessageInfo().getOperation().isUnwrapped();
    if (isFromWrapper && !Boolean.TRUE.equals(part.getProperty("messagepart.isheader"))) {
      UnwrappedOperationInfo uop = (UnwrappedOperationInfo) part.getMessageInfo().getOperation();
      OperationInfo op = uop.getWrappedOperation();
      MessageInfo inf = null;
      if (uop.getInput() == part.getMessageInfo()) {
        inf = op.getInput();
      } else if (uop.getOutput() == part.getMessageInfo()) {
        inf = op.getOutput();
      }
      if (inf != null && inf.getMessagePart(0).getTypeClass() != null) {
        // if the wrapper has a type class, we don't need to do anything
        // as everything would have been discovered when walking the
        // wrapper type (unless it's a header which wouldn't be in the wrapper)
        return;
      }
    }
    if (isFromWrapper && clazz.isArray() && !Byte.TYPE.equals(clazz.getComponentType())) {
      clazz = clazz.getComponentType();
    }

    Annotation[] a = (Annotation[]) part.getProperty("parameter.annotations");
    checkForAdapter(clazz, a);

    Type genericType = (Type) part.getProperty("generic.type");
    if (genericType != null) {
      boolean isList = Collection.class.isAssignableFrom(clazz);
      if (isFromWrapper) {
        if (genericType instanceof Class && ((Class<?>) genericType).isArray()) {
          Class<?> cl2 = (Class<?>) genericType;
          if (cl2.isArray() && !Byte.TYPE.equals(cl2.getComponentType())) {
            genericType = cl2.getComponentType();
          }
          addType(genericType);
        } else if (!isList) {
          addType(genericType);
        }
      } else {
        addType(genericType, true);
      }

      if (isList && genericType instanceof ParameterizedType) {
        ParameterizedType pt = (ParameterizedType) genericType;
        if (pt.getActualTypeArguments().length > 0
            && pt.getActualTypeArguments()[0] instanceof Class) {

          Class<? extends Object> arrayCls =
              Array.newInstance((Class<?>) pt.getActualTypeArguments()[0], 0).getClass();
          clazz = arrayCls;
          part.setTypeClass(clazz);
          if (isFromWrapper) {
            addType(clazz.getComponentType(), true);
          }
        } else if (pt.getActualTypeArguments().length > 0
            && pt.getActualTypeArguments()[0] instanceof GenericArrayType) {
          GenericArrayType gat = (GenericArrayType) pt.getActualTypeArguments()[0];
          gat.getGenericComponentType();
          Class<? extends Object> arrayCls =
              Array.newInstance((Class<?>) gat.getGenericComponentType(), 0).getClass();
          clazz = Array.newInstance(arrayCls, 0).getClass();
          part.setTypeClass(clazz);
          if (isFromWrapper) {
            addType(clazz.getComponentType(), true);
          }
        }
      }
      if (isFromWrapper && isList) {
        clazz = null;
      }
    }
    if (clazz != null) {
      if (!isFromWrapper
          && clazz.getAnnotation(XmlRootElement.class) == null
          && clazz.getAnnotation(XmlType.class) != null
          && StringUtils.isEmpty(clazz.getAnnotation(XmlType.class).name())) {
        Object ref = JAXBClassLoaderUtils.createTypeReference(part.getName(), clazz);
        if (ref != null) {
          typeReferences.add(ref);
        }
      }

      addClass(clazz);
    }
  }