/*
 * Copyright 2015-2016 the original author or authors.
 *
 * All rights reserved. This program and the accompanying materials are
 * made available under the terms of the Eclipse Public License v1.0 which
 * accompanies this distribution and is available at
 *
 * http://www.eclipse.org/legal/epl-v10.html
 */

package org.junit.gen5.api.extension;

import static org.junit.gen5.commons.meta.API.Usage.Experimental;

import java.lang.reflect.Parameter;
import java.util.Optional;

import org.junit.gen5.commons.meta.API;

/**
 * {@code ParameterResolver} defines the API for {@link Extension Extensions}
 * that wish to dynamically resolve {@linkplain Parameter parameters} at runtime.
 *
 * <p>If a constructor for a test class or a
 * {@link org.junit.gen5.api.Test @Test},
 * {@link org.junit.gen5.api.BeforeEach @BeforeEach},
 * {@link org.junit.gen5.api.AfterEach @AfterEach},
 * {@link org.junit.gen5.api.BeforeAll @BeforeAll}, or
 * {@link org.junit.gen5.api.AfterAll @AfterAll} method accepts a parameter,
 * the parameter must be resolved at runtime by a {@code ParameterResolver}.
 *
 * <p>Implementations must provide a no-args constructor.
 *
 * @since 5.0
 * @see #supports(Parameter, Optional, ExtensionContext)
 * @see #resolve(Parameter, Optional, ExtensionContext)
 */
@API(Experimental)
public interface ParameterResolver extends Extension {

	/**
	 * Determine if this resolver supports resolution of the given {@link Parameter}
	 * for the supplied {@code target} and {@link ExtensionContext}.
	 *
	 * <p>The {@link java.lang.reflect.Method} or {@link java.lang.reflect.Constructor}
	 * in which the {@code parameter} is declared can be retrieved via
	 * {@link Parameter#getDeclaringExecutable()}.
	 *
	 * @param parameter the parameter to be resolved
	 * @param target the container for the target on which the {@code java.lang.reflect.Executable}
	 * will be invoked; will be <em>empty</em> if the {@code Executable} is a constructor
	 * or {@code static} method
	 * @param extensionContext the extension context for the {@code Executable}
	 * about to be invoked
	 * @return {@code true} if this resolver can resolve the parameter
	 * @see #resolve
	 * @see java.lang.reflect.Parameter
	 * @see java.lang.reflect.Executable
	 * @see java.lang.reflect.Method
	 * @see java.lang.reflect.Constructor
	 */
	boolean supports(Parameter parameter, Optional<Object> target, ExtensionContext extensionContext)
			throws ParameterResolutionException;

	/**
	 * Resolve the given {@link Parameter} for the supplied {@code target} and
	 * {@link ExtensionContext}.
	 *
	 * <p>The {@link java.lang.reflect.Method} or {@link java.lang.reflect.Constructor}
	 * in which the {@code parameter} is declared can be retrieved via
	 * {@link Parameter#getDeclaringExecutable()}.
	 *
	 * @param parameter the parameter to be resolved
	 * @param target the container for the target on which the {@code java.lang.reflect.Executable}
	 * will be invoked; will be <em>empty</em> if the {@code Executable} is a constructor
	 * or {@code static} method
	 * @param extensionContext the extension context for the {@code Executable}
	 * about to be invoked
	 * @return the resolved parameter object; may only be {@code null} if the
	 * parameter type is not a primitive
	 * @see #supports
	 * @see java.lang.reflect.Parameter
	 * @see java.lang.reflect.Executable
	 * @see java.lang.reflect.Method
	 * @see java.lang.reflect.Constructor
	 */
	Object resolve(Parameter parameter, Optional<Object> target, ExtensionContext extensionContext)
			throws ParameterResolutionException;

}

@@ -1772,38 +1772,74 @@
 lved
-%0A%09 * @param target the
+; never %7B@code null%7D%0A%09 * @param target an %7B@code Optional%7D
  contain
 er f
@@ -1826,38 +1826,35 @@
 ptional%7D contain
-er for
+ing
  the target on w
@@ -1853,32 +1853,36 @@
 get on which the
+%0A%09 *
  %7B@code java.lan
@@ -1894,36 +1894,32 @@
 lect.Executable%7D
-%0A%09 *
  will be invoked
@@ -1912,39 +1912,70 @@
 ill be invoked; 
-will be
+never %7B@code null%7D%0A%09 * but potentially
  %3Cem%3Eempty%3C/em%3E 
@@ -2138,32 +2138,52 @@
 ut to be invoked
+; never %7B@code null%7D
 %0A%09 * @return %7B@c
@@ -2919,38 +2919,74 @@
 lved
-%0A%09 * @param target the
+; never %7B@code null%7D%0A%09 * @param target an %7B@code Optional%7D
  contain
 er f
@@ -2985,14 +2985,11 @@
 tain
-er for
+ing
  the
@@ -3000,32 +3000,36 @@
 get on which the
+%0A%09 *
  %7B@code java.lan
@@ -3049,20 +3049,16 @@
 cutable%7D
-%0A%09 *
  will be
@@ -3067,23 +3067,54 @@
 nvoked; 
-will be
+never %7B@code null%7D%0A%09 * but potentially
  %3Cem%3Eemp
@@ -3262,32 +3262,32 @@
 ode Executable%7D%0A
-
 %09 * about to be 
@@ -3293,16 +3293,36 @@
  invoked
+; never %7B@code null%7D
 %0A%09 * @re

Document nullability of arguments passed to ParameterResolvers