public XmlBeanSerializer(BeanSerializerBase src) {
    super(src);

    /* Then make sure attributes are sorted before elements, keep track
     * of how many there are altogether
     */
    int attrCount = 0;
    for (BeanPropertyWriter bpw : _props) {
      if (_isAttribute(bpw)) { // Yup: let's build re-ordered list then
        attrCount = _orderAttributesFirst(_props, _filteredProps);
        break;
      }
    }
    _attributeCount = attrCount;

    // And then collect namespace information
    _xmlNames = new QName[_props.length];
    int textIndex = -1;
    for (int i = 0, len = _props.length; i < len; ++i) {
      BeanPropertyWriter bpw = _props[i];
      XmlInfo info = (XmlInfo) bpw.getInternalSetting(KEY_XML_INFO);
      String ns = null;
      if (info != null) {
        ns = info.getNamespace();
        if (textIndex < 0 && info.isText()) {
          textIndex = i;
        }
      }
      _xmlNames[i] = new QName((ns == null) ? "" : ns, bpw.getName());
    }
    _textPropertyIndex = textIndex;
  }
  /**
   * Main serialization method needs to be overridden to allow XML-specific extra handling, such as
   * indication of whether to write attributes or elements.
   */
  @Override
  protected void serializeFields(Object bean, JsonGenerator jgen0, SerializerProvider provider)
      throws IOException, JsonGenerationException {
    // 19-Aug-2013, tatu: During 'convertValue()', need to skip
    if (!(jgen0 instanceof ToXmlGenerator)) {
      super.serializeFields(bean, jgen0, provider);
      return;
    }

    final ToXmlGenerator xgen = (ToXmlGenerator) jgen0;
    final BeanPropertyWriter[] props;
    if (_filteredProps != null && provider.getActiveView() != null) {
      props = _filteredProps;
    } else {
      props = _props;
    }

    final int attrCount = _attributeCount;
    if (attrCount > 0) {
      xgen.setNextIsAttribute(true);
    }
    final int textIndex = _textPropertyIndex;
    final QName[] xmlNames = _xmlNames;
    int i = 0;

    try {
      for (final int len = props.length; i < len; ++i) {
        if (i == attrCount) {
          xgen.setNextIsAttribute(false);
        }
        // also: if this is property to write as text ("unwrap"), need to:
        if (i == textIndex) {
          xgen.setNextIsUnwrapped(true);
        }
        xgen.setNextName(xmlNames[i]);
        BeanPropertyWriter prop = props[i];
        if (prop != null) { // can have nulls in filtered list
          prop.serializeAsField(bean, xgen, provider);
        }
        // Reset to avoid next value being written as unwrapped,
        // for example when property is suppressed
        if (i == textIndex) {
          xgen.setNextIsUnwrapped(false);
        }
      }
      if (_anyGetterWriter != null) {
        _anyGetterWriter.getAndSerialize(bean, xgen, provider);
      }
    } catch (Exception e) {
      String name = (i == props.length) ? "[anySetter]" : props[i].getName();
      wrapAndThrow(provider, e, bean, name);
    } catch (StackOverflowError e) { // Bit tricky, can't do more calls as stack is full; so:
      JsonMappingException mapE =
          new JsonMappingException("Infinite recursion (StackOverflowError)");
      String name = (i == props.length) ? "[anySetter]" : props[i].getName();
      mapE.prependPath(new JsonMappingException.Reference(bean, name));
      throw mapE;
    }
  }
 @Override
 public List<BeanPropertyWriter> changeProperties(
     SerializationConfig config,
     BeanDescription beanDesc,
     List<BeanPropertyWriter> beanProperties) {
   for (int i = 0; i < beanProperties.size(); ++i) {
     final BeanPropertyWriter writer = beanProperties.get(i);
     if (Optional.class.isAssignableFrom(writer.getPropertyType())) {
       beanProperties.set(i, new GuavaOptionalBeanPropertyWriter(writer));
     }
   }
   return beanProperties;
 }
 // need to override as we must get unwrapping instance...
 @Override
 public void assignSerializer(JsonSerializer<Object> ser) {
   super.assignSerializer(ser);
   if (_serializer != null) {
     NameTransformer t = _nameTransformer;
     if (_serializer.isUnwrappingSerializer()) {
       t =
           NameTransformer.chainedTransformer(
               t, ((UnwrappingBeanSerializer) _serializer)._nameTransformer);
     }
     _serializer = _serializer.unwrappingSerializer(t);
   }
 }
 protected static boolean _isAttribute(BeanPropertyWriter bpw) {
   XmlInfo info = (XmlInfo) bpw.getInternalSetting(KEY_XML_INFO);
   return (info != null) && info.isAttribute();
 }