class SourceProvider extends AbstractConfigurableProvider implements
    MessageBodyReader<T>, MessageBodyWriter<T> {

    public T readFrom(Class<T> source, Type genericType, Annotation[] annotations, MediaType m,
        MultivaluedMap<String, String> headers, InputStream is)
        throws IOException {

        Class<?> theSource = source;
        if (theSource == Source.class) {
            String s = getPreferredSource();
            if ("sax".equalsIgnoreCase(s) || "cxf.stax".equalsIgnoreCase(s)) {
                theSource = SAXSource.class;
            }
        }
        try {
            if (DOMSource.class.isAssignableFrom(theSource) || Document.class.isAssignableFrom(theSource)) {

                boolean docRequired = Document.class.isAssignableFrom(theSource);
                XMLStreamReader reader = getReader(is);
                try {
                    Document doc = StaxUtils.read(reader);
                    return source.cast(docRequired ? doc : new DOMSource(doc));
                } catch (DepthExceededStaxException e) {
                    throw ExceptionUtils.toWebApplicationException(null, JAXRSUtils.toResponse(413));
                } catch (XMLStreamException e) {
                    if (e.getMessage() != null && e.getMessage().startsWith("Maximum Number")) {
                        throw ExceptionUtils.toWebApplicationException(null, JAXRSUtils.toResponse(413));
                    }
                    throw ExceptionUtils.toBadRequestException(e, null);
                } catch (Exception e) {
                    IOException ioex = new IOException("Problem creating a Source object");
                    ioex.setStackTrace(e.getStackTrace());
                    throw ioex;
                } finally {
                    try {
                        reader.close();
                    } catch (XMLStreamException e) {
                        //ignore
                    }
                }
            } else if (SAXSource.class.isAssignableFrom(theSource)
                      || StaxSource.class.isAssignableFrom(theSource)) {
                return source.cast(new StaxSource(getReader(is)));
            } else if (StreamSource.class.isAssignableFrom(theSource)
                       || Source.class.isAssignableFrom(theSource)) {
                return source.cast(new StreamSource(getRealStream(is)));
            } else if (XMLSource.class.isAssignableFrom(theSource)) {
                return source.cast(new XMLSource(getRealStream(is)));
            }
        } catch (ClassCastException e) {
            String msg = "Unsupported class: " + source.getName();
            LOG.warning(msg);
            throw ExceptionUtils.toInternalServerErrorException(null, null);
        }

        throw new IOException("Unrecognized source");
    }

}