// Path: src/main/java/com/github/ggeorgovassilis/springjsonmapper/model/MappingDeclarationException.java
// public class MappingDeclarationException extends RuntimeException {
// 	protected Method method;
// 	protected Annotation annotation;
// 	protected int parameterIndex;
// 
// 	public MappingDeclarationException(String message, Method method, Annotation annotation, int parameterIndex) {
// 		super(message);
// 		this.method = method;
// 		this.annotation = annotation;
// 		this.parameterIndex = parameterIndex;
// 	}
// 
// 	public MappingDeclarationException(String message, Method method, Throwable throwable) {
// 		super(message, throwable);
// 		this.method = method;
// 	}
// 
// 	public MappingDeclarationException(String message, Method method) {
// 		super(message);
// 		this.method = method;
// 	}
// }
// 
// Path: src/main/java/com/github/ggeorgovassilis/springjsonmapper/model/UrlMapping.java
// public class UrlMapping {
// 
// 	protected HttpMethod httpMethod = HttpMethod.GET;
// 	protected String url = "/";
// 	protected List<MethodParameterDescriptor> parameters = new ArrayList<MethodParameterDescriptor>();
// 	protected String[] headers = new String[0];
// 	protected String[] consumes = new String[0];
// 	protected String[] produces = new String[0];
// 	protected String[] cookies = new String[0];
// 
// 	public String[] getCookies() {
// 		return cookies;
// 	}
// 
// 	public void setCookies(String[] cookies) {
// 		this.cookies = cookies;
// 	}
// 
// 	public String[] getConsumes() {
// 		return consumes;
// 	}
// 
// 	public void setConsumes(String[] consumes) {
// 		this.consumes = consumes;
// 	}
// 
// 	public String[] getProduces() {
// 		return produces;
// 	}
// 
// 	public void setProduces(String[] produces) {
// 		this.produces = produces;
// 	}
// 
// 	public String[] getHeaders() {
// 		return headers;
// 	}
// 
// 	public void setHeaders(String[] headers) {
// 		this.headers = headers;
// 	}
// 
// 	public String getUrl() {
// 		return url;
// 	}
// 
// 	public void setUrl(String url) {
// 		this.url = url;
// 	}
// 
// 	public HttpMethod getHttpMethod() {
// 		return httpMethod;
// 	}
// 
// 	public void setHttpMethod(HttpMethod httpMethod) {
// 		this.httpMethod = httpMethod;
// 	}
// 
// 	public List<MethodParameterDescriptor> getParameters() {
// 		return parameters;
// 	}
// 
// 	public void setParameters(List<MethodParameterDescriptor> parameters) {
// 		this.parameters = parameters;
// 	}
// 
// 	public void addDescriptor(MethodParameterDescriptor descriptor) {
// 		parameters.add(descriptor);
// 	}
// 
// 	public boolean hasRequestBody(String parameter) {
// 		for (MethodParameterDescriptor descriptor : parameters)
// 			if (parameter.equals(descriptor.getName())
// 					&& (descriptor.getType().equals(Type.requestBody) || descriptor.getType().equals(Type.requestPart)))
// 				return true;
// 		return false;
// 	}
// }
// 
// Path: src/main/java/com/github/ggeorgovassilis/springjsonmapper/spring/mapping/MappingAnnotationResolver.java
// public interface MappingAnnotationResolver<T extends Annotation> {
// 	UrlMapping resolve(T mappingAnnotation);
// 
// 	boolean supported(Class<T> annotation);
// }


import com.github.ggeorgovassilis.springjsonmapper.model.MappingDeclarationException;
import com.github.ggeorgovassilis.springjsonmapper.model.UrlMapping;
import com.github.ggeorgovassilis.springjsonmapper.spring.mapping.MappingAnnotationResolver;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.web.bind.annotation.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;
		}
		if (methodUrlMapping.getProduces().length == 0) {
			methodUrlMapping.setProduces(classUrlMapping.getProduces());
		}
		if (methodUrlMapping.getHeaders().length == 0) {
			methodUrlMapping.setHeaders(classUrlMapping.getHeaders());
		}
		return methodUrlMapping;
	}
	
	private UrlMapping resolveFor(AnnotatedElement annotatedElement) {
		return Stream.of(
				AnnotatedElementUtils.getMergedAnnotation(annotatedElement, RequestMapping.class),
				AnnotatedElementUtils.getMergedAnnotation(annotatedElement, GetMapping.class),
				AnnotatedElementUtils.getMergedAnnotation(annotatedElement, PostMapping.class),
				AnnotatedElementUtils.getMergedAnnotation(annotatedElement, PutMapping.class),
				AnnotatedElementUtils.getMergedAnnotation(annotatedElement, PatchMapping.class),
				AnnotatedElementUtils.getMergedAnnotation(annotatedElement, DeleteMapping.class))
				.filter(Objects::nonNull)
				.findFirst()
				.map(a -> getResolver(a).resolve(a))
				.orElse(null);
	}
	
	private MappingAnnotationResolver getResolver(Annotation annotation) {
		for (MappingAnnotationResolver candidate : mappingAnnotationResolvers) {
			if (candidate.supported(annotation.getClass())) {
				return candidate;
			}
		}
// Path: src/main/java/com/github/ggeorgovassilis/springjsonmapper/model/MappingDeclarationException.java
// public class MappingDeclarationException extends RuntimeException {
// 	protected Method method;
// 	protected Annotation annotation;
// 	protected int parameterIndex;
// 
// 	public MappingDeclarationException(String message, Method method, Annotation annotation, int parameterIndex) {
// 		super(message);
// 		this.method = method;
// 		this.annotation = annotation;
// 		this.parameterIndex = parameterIndex;
// 	}
// 
// 	public MappingDeclarationException(String message, Method method, Throwable throwable) {
// 		super(message, throwable);
// 		this.method = method;
// 	}
// 
// 	public MappingDeclarationException(String message, Method method) {
// 		super(message);
// 		this.method = method;
// 	}
// }
// 
// Path: src/main/java/com/github/ggeorgovassilis/springjsonmapper/model/UrlMapping.java
// public class UrlMapping {
// 
// 	protected HttpMethod httpMethod = HttpMethod.GET;
// 	protected String url = "/";
// 	protected List<MethodParameterDescriptor> parameters = new ArrayList<MethodParameterDescriptor>();
// 	protected String[] headers = new String[0];
// 	protected String[] consumes = new String[0];
// 	protected String[] produces = new String[0];
// 	protected String[] cookies = new String[0];
// 
// 	public String[] getCookies() {
// 		return cookies;
// 	}
// 
// 	public void setCookies(String[] cookies) {
// 		this.cookies = cookies;
// 	}
// 
// 	public String[] getConsumes() {
// 		return consumes;
// 	}
// 
// 	public void setConsumes(String[] consumes) {
// 		this.consumes = consumes;
// 	}
// 
// 	public String[] getProduces() {
// 		return produces;
// 	}
// 
// 	public void setProduces(String[] produces) {
// 		this.produces = produces;
// 	}
// 
// 	public String[] getHeaders() {
// 		return headers;
// 	}
// 
// 	public void setHeaders(String[] headers) {
// 		this.headers = headers;
// 	}
// 
// 	public String getUrl() {
// 		return url;
// 	}
// 
// 	public void setUrl(String url) {
// 		this.url = url;
// 	}
// 
// 	public HttpMethod getHttpMethod() {
// 		return httpMethod;
// 	}
// 
// 	public void setHttpMethod(HttpMethod httpMethod) {
// 		this.httpMethod = httpMethod;
// 	}
// 
// 	public List<MethodParameterDescriptor> getParameters() {
// 		return parameters;
// 	}
// 
// 	public void setParameters(List<MethodParameterDescriptor> parameters) {
// 		this.parameters = parameters;
// 	}
// 
// 	public void addDescriptor(MethodParameterDescriptor descriptor) {
// 		parameters.add(descriptor);
// 	}
// 
// 	public boolean hasRequestBody(String parameter) {
// 		for (MethodParameterDescriptor descriptor : parameters)
// 			if (parameter.equals(descriptor.getName())
// 					&& (descriptor.getType().equals(Type.requestBody) || descriptor.getType().equals(Type.requestPart)))
// 				return true;
// 		return false;
// 	}
// }
// 
// Path: src/main/java/com/github/ggeorgovassilis/springjsonmapper/spring/mapping/MappingAnnotationResolver.java
// public interface MappingAnnotationResolver<T extends Annotation> {
// 	UrlMapping resolve(T mappingAnnotation);
// 
// 	boolean supported(Class<T> annotation);
// }


// Path: src/main/java/com/github/ggeorgovassilis/springjsonmapper/spring/MappingAnnotationsInspector.java
import com.github.ggeorgovassilis.springjsonmapper.model.MappingDeclarationException;
import com.github.ggeorgovassilis.springjsonmapper.model.UrlMapping;
import com.github.ggeorgovassilis.springjsonmapper.spring.mapping.MappingAnnotationResolver;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.web.bind.annotation.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;

		}
		if (methodUrlMapping.getProduces().length == 0) {
			methodUrlMapping.setProduces(classUrlMapping.getProduces());
		}
		if (methodUrlMapping.getHeaders().length == 0) {
			methodUrlMapping.setHeaders(classUrlMapping.getHeaders());
		}
		return methodUrlMapping;
	}
	
	private UrlMapping resolveFor(AnnotatedElement annotatedElement) {
		return Stream.of(
				AnnotatedElementUtils.getMergedAnnotation(annotatedElement, RequestMapping.class),
				AnnotatedElementUtils.getMergedAnnotation(annotatedElement, GetMapping.class),
				AnnotatedElementUtils.getMergedAnnotation(annotatedElement, PostMapping.class),
				AnnotatedElementUtils.getMergedAnnotation(annotatedElement, PutMapping.class),
				AnnotatedElementUtils.getMergedAnnotation(annotatedElement, PatchMapping.class),
				AnnotatedElementUtils.getMergedAnnotation(annotatedElement, DeleteMapping.class))
				.filter(Objects::nonNull)
				.findFirst()
				.map(a -> getResolver(a).resolve(a))
				.orElse(null);
	}
	
	private MappingAnnotationResolver getResolver(Annotation annotation) {
		for (MappingAnnotationResolver candidate : mappingAnnotationResolvers) {
			if (candidate.supported(annotation.getClass())) {
				return candidate;
			}
		}
		throw new MappingDeclarationException("Not implemented resolver for annotation ", null, annotation, -1);