Separate Payara's inserters from PR 3844 (#4098)

Signed-off-by: jGauravGupta <gaurav.gupta.jc@gmail.com>
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/ClientBootstrapBag.java b/core-client/src/main/java/org/glassfish/jersey/client/ClientBootstrapBag.java
new file mode 100644
index 0000000..3c85855
--- /dev/null
+++ b/core-client/src/main/java/org/glassfish/jersey/client/ClientBootstrapBag.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2018 Payara Foundation and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+package org.glassfish.jersey.client;
+
+
+import org.glassfish.jersey.internal.BootstrapBag;
+import org.glassfish.jersey.client.inject.ParameterInserterProvider;
+
+/**
+ * {@inheritDoc}
+ * <p>
+ * This bootstrap bag is specialized for client part of Jersey.
+ *
+ * @author Gaurav Gupta (gaurav.gupta@payara.fish)
+ */
+public class ClientBootstrapBag extends BootstrapBag {
+
+    private ParameterInserterProvider parameterInserterProvider;
+
+    public ParameterInserterProvider getParameterInserterProvider() {
+        requireNonNull(parameterInserterProvider, ParameterInserterProvider.class);
+        return parameterInserterProvider;
+    }
+
+    public void setParameterInserterProvider(ParameterInserterProvider provider) {
+        this.parameterInserterProvider = provider;
+    }
+}
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/ClientConfig.java b/core-client/src/main/java/org/glassfish/jersey/client/ClientConfig.java
index fb2ea46..bf0e4ee 100644
--- a/core-client/src/main/java/org/glassfish/jersey/client/ClientConfig.java
+++ b/core-client/src/main/java/org/glassfish/jersey/client/ClientConfig.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Payara Foundation and/or its affiliates.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -34,6 +35,7 @@
 import org.glassfish.jersey.CommonProperties;
 import org.glassfish.jersey.ExtendedConfig;
 import org.glassfish.jersey.client.internal.LocalizationMessages;
+import org.glassfish.jersey.client.internal.inject.ParameterInserterConfigurator;
 import org.glassfish.jersey.client.spi.Connector;
 import org.glassfish.jersey.client.spi.ConnectorProvider;
 import org.glassfish.jersey.internal.AutoDiscoverableConfigurator;
@@ -56,6 +58,7 @@
 import org.glassfish.jersey.model.internal.ComponentBag;
 import org.glassfish.jersey.model.internal.ManagedObjectsFinalizer;
 import org.glassfish.jersey.process.internal.RequestScope;
+import org.glassfish.jersey.internal.inject.ParamConverterConfigurator;
 
 /**
  * Jersey externalized implementation of client-side JAX-RS {@link javax.ws.rs.core.Configurable
@@ -64,6 +67,7 @@
  * @author Marek Potociar (marek.potociar at oracle.com)
  * @author Martin Matula
  * @author Libor Kramolis (libor.kramolis at oracle.com)
+ * @author Gaurav Gupta (gaurav.gupta@payara.fish)
  */
 public class ClientConfig implements Configurable<ClientConfig>, ExtendedConfig {
     /**
@@ -408,10 +412,11 @@
             InjectionManager injectionManager = Injections.createInjectionManager();
             injectionManager.register(new ClientBinder(runtimeCfgState.getProperties()));
 
-            BootstrapBag bootstrapBag = new BootstrapBag();
+            BootstrapBag bootstrapBag = new ClientBootstrapBag();
             bootstrapBag.setManagedObjectsFinalizer(new ManagedObjectsFinalizer(injectionManager));
-            List<BootstrapConfigurator> bootstrapConfigurators = Arrays.asList(
-                    new RequestScope.RequestScopeConfigurator(),
+            List<BootstrapConfigurator> bootstrapConfigurators = Arrays.asList(new RequestScope.RequestScopeConfigurator(),
+                    new ParamConverterConfigurator(),
+                    new ParameterInserterConfigurator(),
                     new RuntimeConfigConfigurator(runtimeCfgState),
                     new ContextResolverFactory.ContextResolversConfigurator(),
                     new MessageBodyFactory.MessageBodyWorkersConfigurator(),
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/inject/ParameterInserter.java b/core-client/src/main/java/org/glassfish/jersey/client/inject/ParameterInserter.java
new file mode 100644
index 0000000..8b94e61
--- /dev/null
+++ b/core-client/src/main/java/org/glassfish/jersey/client/inject/ParameterInserter.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2010, 2017 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Payara Foundation and/or its affiliates.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.client.inject;
+
+/**
+ * Provider that converts the an object of a custom Java type
+ * values to String / Collection&lt;String>&gt; type
+ *
+ * @param <T> custom Java type
+ * @param <R> String / Collection&lt;String>&gt; type
+ *
+ * @author Paul Sandoz
+ * @author Marek Potociar (marek.potociar at oracle.com)
+ * @author Gaurav Gupta (gaurav.gupta@payara.fish)
+ */
+public interface ParameterInserter<T, R> {
+
+    /**
+     * Name of the parameter to be inserted
+     *
+     * @return name of the inserted parameter.
+     */
+    String getName();
+
+    /**
+     * Default value (string) that will be used in case input value is not available.
+     *
+     * @return default (back-up) value.
+     */
+    String getDefaultValueString();
+
+    /**
+     * Insert the value using ParamConverter#toString (and using
+     * the configured {@link #getDefaultValueString() default value})
+     *
+     * @param parameters custom Java type instance value.
+     * @return converted value.
+     */
+    R insert(T parameters);
+}
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/inject/ParameterInserterProvider.java b/core-client/src/main/java/org/glassfish/jersey/client/inject/ParameterInserterProvider.java
new file mode 100644
index 0000000..4b29d6a
--- /dev/null
+++ b/core-client/src/main/java/org/glassfish/jersey/client/inject/ParameterInserterProvider.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2010, 2017 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Payara Foundation and/or its affiliates.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.client.inject;
+
+import org.glassfish.jersey.model.Parameter;
+
+/**
+ * Provider of parameter inserter.
+ *
+ * @author Paul Sandoz
+ * @author Marek Potociar (marek.potociar at oracle.com)
+ * @author Gaurav Gupta (gaurav.gupta@payara.fish)
+ */
+public interface ParameterInserterProvider {
+
+    /**
+     * Get the inserter configured to insert value of given {@link Parameter parameter}.
+     * <p />
+     * If the default value has been set on the parameter, it will be configured
+     * in the inserter.
+     *
+     * @param parameter client model parameter.
+     * @return inserter for the method parameter.
+     */
+    ParameterInserter<?, ?> get(Parameter parameter);
+}
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/internal/inject/AbstractParamValueInserter.java b/core-client/src/main/java/org/glassfish/jersey/client/internal/inject/AbstractParamValueInserter.java
new file mode 100644
index 0000000..28d508b
--- /dev/null
+++ b/core-client/src/main/java/org/glassfish/jersey/client/internal/inject/AbstractParamValueInserter.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2010, 2017 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Payara Foundation and/or its affiliates.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.client.internal.inject;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.ext.ParamConverter;
+
+import org.glassfish.jersey.internal.inject.InserterException;
+import org.glassfish.jersey.internal.util.collection.UnsafeValue;
+import org.glassfish.jersey.internal.util.collection.Values;
+
+/**
+ * Abstract base class for implementing parameter value inserter
+ * logic supplied using {@link ParamConverter parameter converters}.
+ *
+ * @author Paul Sandoz
+ * @author Marek Potociar (marek.potociar at oracle.com)
+ * @author Gaurav Gupta (gaurav.gupta@payara.fish)
+ */
+abstract class AbstractParamValueInserter<T> {
+
+    private final ParamConverter<T> paramConverter;
+    private final String parameterName;
+    private final String defaultValue;
+    private final UnsafeValue<String, RuntimeException> convertedDefaultValue;
+
+    /**
+     * Constructor that initializes parameter inserter.
+     *
+     * @param converter          parameter converter.
+     * @param parameterName      name of the parameter.
+     * @param defaultValueString default parameter value string.
+     */
+    protected AbstractParamValueInserter(ParamConverter<T> converter, String parameterName, final String defaultValue) {
+        this.paramConverter = converter;
+        this.parameterName = parameterName;
+        this.defaultValue = defaultValue;
+
+        if (defaultValue != null) {
+            this.convertedDefaultValue = Values.lazy(new UnsafeValue<String, RuntimeException>() {
+                @Override
+                public String get() throws RuntimeException {
+                    return defaultValue;
+                }
+            });
+
+            if (!converter.getClass().isAnnotationPresent(ParamConverter.Lazy.class)) {
+                // ignore return value - executed just for validation reasons
+                convertedDefaultValue.get();
+            }
+        } else {
+            convertedDefaultValue = null;
+        }
+    }
+
+    /**
+     * Get the name of the parameter this inserter belongs to.
+     *
+     * @return parameter name.
+     */
+    public String getName() {
+        return parameterName;
+    }
+
+    /**
+     * Get the default value of the parameter.
+     *
+     * @return default parameter value.
+     */
+    public String getDefaultValueString() {
+        return defaultValue;
+    }
+
+    /**
+     * Insert parameter value to string using the configured {@link ParamConverter parameter converter}.
+     *
+     * A {@link WebApplicationException} / {@link IllegalArgumentException} thrown
+     * from the converter is propagated unchanged. Any other exception throws by
+     * the converter is wrapped in a new {@link InserterException} before rethrowing.
+     *
+     * @param value parameter value to be converted/inserted.
+     * @return inserted value of a given Java type.
+     * @throws WebApplicationException in case the underlying parameter converter throws
+     * a {@code WebApplicationException}. The exception is rethrown without a change.
+     * @throws InserterException wrapping any other exception thrown by the parameter converter.
+     */
+    protected final String toString(T value) {
+        String result = convert(value);
+        if (result == null) {
+            return defaultValue();
+        }
+        return result;
+    }
+
+    private String convert(T value) {
+        try {
+            return paramConverter.toString(value);
+        } catch (WebApplicationException | IllegalArgumentException ex) {
+            throw ex;
+        } catch (Exception ex) {
+            throw new InserterException(ex);
+        }
+    }
+
+    /**
+     * Check if there is a default value registered for the parameter.
+     *
+     * @return {@code true} if there is a default parameter value registered, {@code false} otherwise.
+     */
+    protected final boolean isDefaultValueRegistered() {
+        return defaultValue != null;
+    }
+
+    /**
+     * Get converted default value.
+     *
+     * The conversion happens lazily during first call of the method.
+     *
+     * @return converted default value.
+     */
+    protected final String defaultValue() {
+        if (!isDefaultValueRegistered()) {
+            return null;
+        }
+
+        return convertedDefaultValue.get();
+    }
+}
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/internal/inject/CollectionInserter.java b/core-client/src/main/java/org/glassfish/jersey/client/internal/inject/CollectionInserter.java
new file mode 100644
index 0000000..0902d76
--- /dev/null
+++ b/core-client/src/main/java/org/glassfish/jersey/client/internal/inject/CollectionInserter.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2010, 2017 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Payara Foundation and/or its affiliates.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.client.internal.inject;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import static java.util.stream.Collectors.toList;
+import javax.ws.rs.ProcessingException;
+import javax.ws.rs.ext.ParamConverter;
+import org.glassfish.jersey.client.internal.LocalizationMessages;
+import org.glassfish.jersey.client.inject.ParameterInserter;
+
+/**
+ * Insert parameter value as a typed collection.
+ *
+ * @param <T> parameter value type.
+ * @author Paul Sandoz
+ * @author Marek Potociar (marek.potociar at oracle.com)
+ * @author Gaurav Gupta (gaurav.gupta@payara.fish)
+ */
+abstract class CollectionInserter<T> extends AbstractParamValueInserter<T>
+        implements ParameterInserter<Collection<T>, Collection<String>> {
+
+    /**
+     * Create new collection parameter inserter.
+     *
+     * @param converter          parameter converter to be used to convert parameter from a custom Java type.
+     * @param parameterName      parameter name.
+     * @param defaultValue default parameter String value.
+     */
+    protected CollectionInserter(final ParamConverter<T> converter,
+                                  final String parameterName,
+                                  final String defaultValue) {
+        super(converter, parameterName, defaultValue);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public Collection<String> insert(final Collection<T> values) {
+        Collection<String> results = Collections.EMPTY_LIST;
+        if (values != null) {
+            results = values
+                    .stream()
+                    .map(item -> toString(item))
+                    .collect(toList());
+        } else if (isDefaultValueRegistered()) {
+            results = Collections.singletonList(getDefaultValueString());
+        }
+        return results;
+    }
+
+    /**
+     * Get a new collection instance that will be used to store the inserted parameters.
+     * <p/>
+     * The method is overridden by concrete implementations to return an instance
+     * of a proper collection sub-type.
+     *
+     * @return instance of a proper collection sub-type
+     */
+    protected abstract Collection<String> newCollection();
+
+    private static final class ListValueOf<T> extends CollectionInserter<T> {
+
+        ListValueOf(final ParamConverter<T> converter, final String parameter, final String defaultValue) {
+            super(converter, parameter, defaultValue);
+        }
+
+        @Override
+        protected List<String> newCollection() {
+            return new ArrayList<>();
+        }
+    }
+
+    private static final class SetValueOf<T> extends CollectionInserter<T> {
+
+        SetValueOf(final ParamConverter<T> converter, final String parameter, final String defaultValue) {
+            super(converter, parameter, defaultValue);
+        }
+
+        @Override
+        protected Set<String> newCollection() {
+            return new HashSet<>();
+        }
+    }
+
+    private static final class SortedSetValueOf<T> extends CollectionInserter<T> {
+
+        SortedSetValueOf(final ParamConverter<T> converter, final String parameter, final String defaultValue) {
+            super(converter, parameter, defaultValue);
+        }
+
+        @Override
+        protected SortedSet<String> newCollection() {
+            return new TreeSet<>();
+        }
+    }
+
+    /**
+     * Get a new {@code CollectionInserter} instance.
+     *
+     * @param collectionType     raw collection type.
+     * @param converter          parameter converter to be used to convert parameter Java type values into
+     *                           String values .
+     * @param parameterName      parameter name.
+     * @param defaultValue default parameter string value.
+     * @param <T>                converted parameter Java type.
+     * @return new collection parameter inserter instance.
+     */
+    public static <T> CollectionInserter getInstance(final Class<?> collectionType,
+                                                      final ParamConverter<T> converter,
+                                                      final String parameterName,
+                                                      final String defaultValue) {
+        if (List.class == collectionType) {
+            return new ListValueOf<>(converter, parameterName, defaultValue);
+        } else if (Set.class == collectionType) {
+            return new SetValueOf<>(converter, parameterName, defaultValue);
+        } else if (SortedSet.class == collectionType) {
+            return new SortedSetValueOf<>(converter, parameterName, defaultValue);
+        } else {
+            throw new ProcessingException(LocalizationMessages.COLLECTION_INSERTER_TYPE_UNSUPPORTED());
+        }
+    }
+}
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/internal/inject/ParameterInserterConfigurator.java b/core-client/src/main/java/org/glassfish/jersey/client/internal/inject/ParameterInserterConfigurator.java
new file mode 100644
index 0000000..a75a272
--- /dev/null
+++ b/core-client/src/main/java/org/glassfish/jersey/client/internal/inject/ParameterInserterConfigurator.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Payara Foundation and/or its affiliates.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.client.internal.inject;
+
+import javax.ws.rs.ext.ParamConverterProvider;
+import org.glassfish.jersey.client.ClientBootstrapBag;
+
+import org.glassfish.jersey.internal.BootstrapBag;
+import org.glassfish.jersey.internal.BootstrapConfigurator;
+import org.glassfish.jersey.internal.inject.Bindings;
+import org.glassfish.jersey.internal.inject.InjectionManager;
+import org.glassfish.jersey.internal.inject.ParamConverterFactory;
+import org.glassfish.jersey.internal.inject.Providers;
+import org.glassfish.jersey.internal.util.collection.LazyValue;
+import org.glassfish.jersey.internal.util.collection.Value;
+import org.glassfish.jersey.internal.util.collection.Values;
+import org.glassfish.jersey.client.inject.ParameterInserterProvider;
+
+/**
+ * Configurator which initializes and register {@link ParameterInserterProvider} instance into
+ * {@link InjectionManager}.
+ *
+ * @author Petr Bouda
+ * @author Gaurav Gupta (gaurav.gupta@payara.fish)
+ */
+public class ParameterInserterConfigurator implements BootstrapConfigurator {
+
+    @Override
+    public void init(InjectionManager injectionManager, BootstrapBag bootstrapBag) {
+        ClientBootstrapBag clientBag = (ClientBootstrapBag) bootstrapBag;
+
+        // Param Converters must be initialized Lazy and created at the time of the call on inserter
+        LazyValue<ParamConverterFactory> lazyParamConverterFactory =
+                Values.lazy((Value<ParamConverterFactory>) () -> new ParamConverterFactory(
+                        Providers.getProviders(injectionManager, ParamConverterProvider.class),
+                        Providers.getCustomProviders(injectionManager, ParamConverterProvider.class)));
+
+        ParameterInserterFactory parameterInserter = new ParameterInserterFactory(lazyParamConverterFactory);
+        clientBag.setParameterInserterProvider(parameterInserter);
+        injectionManager.register(Bindings.service(parameterInserter)
+                        .to(ParameterInserterProvider.class));
+    }
+}
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/internal/inject/ParameterInserterFactory.java b/core-client/src/main/java/org/glassfish/jersey/client/internal/inject/ParameterInserterFactory.java
new file mode 100644
index 0000000..9fa283a
--- /dev/null
+++ b/core-client/src/main/java/org/glassfish/jersey/client/internal/inject/ParameterInserterFactory.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2010, 2017 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Payara Foundation and/or its affiliates.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.client.internal.inject;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.List;
+import java.util.Set;
+import java.util.SortedSet;
+import javax.ws.rs.ProcessingException;
+import javax.ws.rs.ext.ParamConverter;
+import javax.inject.Singleton;
+import org.glassfish.jersey.internal.inject.InserterException;
+import org.glassfish.jersey.internal.inject.ParamConverterFactory;
+import org.glassfish.jersey.internal.util.ReflectionHelper;
+import org.glassfish.jersey.internal.util.collection.ClassTypePair;
+import org.glassfish.jersey.internal.util.collection.LazyValue;
+import org.glassfish.jersey.client.internal.LocalizationMessages;
+import org.glassfish.jersey.model.Parameter;
+import org.glassfish.jersey.internal.inject.PrimitiveMapper;
+import org.glassfish.jersey.client.inject.ParameterInserter;
+import org.glassfish.jersey.client.inject.ParameterInserterProvider;
+
+/**
+ * Implementation of {@link ParameterInserterProvider}. For each
+ * parameter, the implementation obtains a
+ * {@link ParamConverter param converter} instance via
+ * {@link ParamConverterFactory} and creates the proper
+ * {@link ParameterInserter parameter inserter}.
+ *
+ * @author Paul Sandoz
+ * @author Marek Potociar (marek.potociar at oracle.com)
+ * @author Gaurav Gupta (gaurav.gupta@payara.fish)
+ */
+@Singleton
+final class ParameterInserterFactory implements ParameterInserterProvider {
+
+    private final LazyValue<ParamConverterFactory> paramConverterFactory;
+
+    /**
+     * Create new parameter inserter factory.
+     *
+     * @param paramConverterFactory string readers factory.
+     */
+    public ParameterInserterFactory(LazyValue<ParamConverterFactory> paramConverterFactory) {
+        this.paramConverterFactory = paramConverterFactory;
+    }
+
+    @Override
+    public ParameterInserter<?, ?> get(final Parameter p) {
+        return process(
+                paramConverterFactory.get(),
+                p.getDefaultValue(),
+                p.getRawType(),
+                p.getType(),
+                p.getAnnotations(),
+                p.getSourceName());
+    }
+
+    @SuppressWarnings("unchecked")
+    private ParameterInserter<?, ?> process(
+            final ParamConverterFactory paramConverterFactory,
+            final String defaultValue,
+            final Class<?> rawType,
+            final Type type,
+            final Annotation[] annotations,
+            final String parameterName) {
+
+        // Try to find a converter that support rawType and type at first.
+        // E.g. if someone writes a converter that support List<Integer> this approach should precede the next one.
+        ParamConverter<?> converter = paramConverterFactory.getConverter(rawType, type, annotations);
+        if (converter != null) {
+            try {
+                return new SingleValueInserter(converter, parameterName, defaultValue);
+            } catch (final InserterException e) {
+                throw e;
+            } catch (final Exception e) {
+                throw new ProcessingException(LocalizationMessages.ERROR_PARAMETER_TYPE_PROCESSING(rawType), e);
+            }
+        }
+
+        // Check whether the rawType is the type of the collection supported.
+        if (rawType == List.class || rawType == Set.class || rawType == SortedSet.class) {
+            // Get the generic type of the list. If none is found default to String.
+            final List<ClassTypePair> typePairs = ReflectionHelper.getTypeArgumentAndClass(type);
+            final ClassTypePair typePair = (typePairs.size() == 1) ? typePairs.get(0) : null;
+
+            if (typePair != null) {
+                converter = paramConverterFactory.getConverter(
+                        typePair.rawClass(),
+                        typePair.type(),
+                        annotations
+                );
+            }
+            if (converter != null) {
+                try {
+                    return CollectionInserter.getInstance(rawType, converter, parameterName, defaultValue);
+                } catch (final InserterException e) {
+                    throw e;
+                } catch (final Exception e) {
+                    throw new ProcessingException(LocalizationMessages.ERROR_PARAMETER_TYPE_PROCESSING(rawType), e);
+                }
+            }
+        }
+
+        // Check primitive types.
+        if (rawType == String.class) {
+            return new SingleStringValueInserter(parameterName, defaultValue);
+        } else if (rawType == Character.class) {
+            return new PrimitiveCharacterInserter(parameterName,
+                    defaultValue,
+                    PrimitiveMapper.primitiveToDefaultValueMap.get(rawType));
+        } else if (rawType.isPrimitive()) {
+            // Convert primitive to wrapper class
+            final Class<?> wrappedRaw = PrimitiveMapper.primitiveToClassMap.get(rawType);
+            if (wrappedRaw == null) {
+                // Primitive type not supported
+                return null;
+            }
+
+            if (wrappedRaw == Character.class) {
+                return new PrimitiveCharacterInserter(parameterName,
+                        defaultValue,
+                        PrimitiveMapper.primitiveToDefaultValueMap.get(wrappedRaw));
+            }
+
+            return new PrimitiveValueOfInserter(
+                    parameterName,
+                    defaultValue,
+                    PrimitiveMapper.primitiveToDefaultValueMap.get(wrappedRaw));
+        }
+
+        return null;
+    }
+}
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/internal/inject/PrimitiveCharacterInserter.java b/core-client/src/main/java/org/glassfish/jersey/client/internal/inject/PrimitiveCharacterInserter.java
new file mode 100644
index 0000000..5d80ec7
--- /dev/null
+++ b/core-client/src/main/java/org/glassfish/jersey/client/internal/inject/PrimitiveCharacterInserter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2015, 2017 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Payara Foundation and/or its affiliates.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.client.internal.inject;
+
+import org.glassfish.jersey.client.inject.ParameterInserter;
+
+/**
+ * Value inserter for {@link java.lang.Character} and {@code char} parameters.
+ *
+ * @author Pavel Bucek (pavel.bucek at oracle.com)
+ * @author Gaurav Gupta (gaurav.gupta@payara.fish)
+ *
+ */
+class PrimitiveCharacterInserter implements ParameterInserter<Character, String> {
+
+    private final String parameter;
+    private final String defaultValue;
+    private final Object defaultPrimitiveTypeValue;
+
+    public PrimitiveCharacterInserter(String parameter, String defaultValue, Object defaultPrimitiveTypeValue) {
+        this.parameter = parameter;
+        this.defaultValue = defaultValue;
+        this.defaultPrimitiveTypeValue = defaultPrimitiveTypeValue;
+    }
+
+    @Override
+    public String getName() {
+        return parameter;
+    }
+
+    @Override
+    public String getDefaultValueString() {
+        return defaultValue;
+    }
+
+    @Override
+    public String insert(Character value) {
+        if (value != null) {
+            return value.toString();
+        } else if (defaultValue != null) {
+            return defaultValue;
+        }
+        return defaultPrimitiveTypeValue.toString();
+    }
+}
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/internal/inject/PrimitiveValueOfInserter.java b/core-client/src/main/java/org/glassfish/jersey/client/internal/inject/PrimitiveValueOfInserter.java
new file mode 100644
index 0000000..9e1ccc8
--- /dev/null
+++ b/core-client/src/main/java/org/glassfish/jersey/client/internal/inject/PrimitiveValueOfInserter.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2010, 2017 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Payara Foundation and/or its affiliates.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.client.internal.inject;
+
+import org.glassfish.jersey.client.inject.ParameterInserter;
+
+/**
+ * Insert String value using {@code toString()} methods
+ * on the primitive Java type wrapper classes.
+ *
+ * @author Paul Sandoz
+ * @author Marek Potociar (marek.potociar at oracle.com)
+ * @author Gaurav Gupta (gaurav.gupta@payara.fish)
+ *
+ */
+final class PrimitiveValueOfInserter implements ParameterInserter<Number, String> {
+
+    private final String parameter;
+    private final String defaultValue;
+    private final Object defaultPrimitiveTypeValue;
+
+    /**
+     * Create new primitive parameter value inserter.
+     *
+     * @param valueOf {@code valueOf()} method handler.
+     * @param parameter string parameter value.
+     * @param defaultValue default string value.
+     * @param defaultPrimitiveTypeValue default primitive type value.
+     */
+    public PrimitiveValueOfInserter(String parameter,
+            String defaultValue,
+            Object defaultPrimitiveTypeValue) {
+        this.parameter = parameter;
+        this.defaultValue = defaultValue;
+        this.defaultPrimitiveTypeValue = defaultPrimitiveTypeValue;
+    }
+
+    @Override
+    public String getName() {
+        return parameter;
+    }
+
+    @Override
+    public String getDefaultValueString() {
+        return defaultValue;
+    }
+
+    @Override
+    public String insert(Number value) {
+        if (value != null) {
+            return value.toString();
+        } else if (defaultValue != null) {
+            return defaultValue;
+        }
+        return defaultPrimitiveTypeValue.toString();
+    }
+}
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/internal/inject/SingleStringValueInserter.java b/core-client/src/main/java/org/glassfish/jersey/client/internal/inject/SingleStringValueInserter.java
new file mode 100644
index 0000000..03973e4
--- /dev/null
+++ b/core-client/src/main/java/org/glassfish/jersey/client/internal/inject/SingleStringValueInserter.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2010, 2017 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Payara Foundation and/or its affiliates.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.client.internal.inject;
+
+import org.glassfish.jersey.client.inject.ParameterInserter;
+
+/**
+ * Insert value of the parameter by returning the first string parameter value
+ * found in the list of string parameter values.
+ * <p />
+ * This class can be seen as a special, optimized, case of {@link SingleValueInserter}.
+ *
+ * @author Paul Sandoz
+ * @author Marek Potociar (marek.potociar at oracle.com)
+ * @author Gaurav Gupta (gaurav.gupta@payara.fish)
+ */
+final class SingleStringValueInserter implements ParameterInserter<String, String> {
+
+    private final String paramName;
+    private final String defaultValue;
+
+    /**
+     * Create new single string value inserter.
+     *
+     * @param parameterName string parameter name.
+     * @param defaultValue  default value.
+     */
+    public SingleStringValueInserter(String parameterName, String defaultValue) {
+        this.paramName = parameterName;
+        this.defaultValue = defaultValue;
+    }
+
+    @Override
+    public String getName() {
+        return paramName;
+    }
+
+    @Override
+    public String getDefaultValueString() {
+        return defaultValue;
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p/>
+     * This implementation return s the first String value found in the list of
+     * potential multiple string parameter values. Any other values in the multi-value
+     * list will be ignored.
+     *
+     * @param parameters map of parameters.
+     * @return inserted single string parameter value.
+     */
+    @Override
+    public String insert(String value) {
+        return (value != null) ? value : defaultValue;
+    }
+}
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/internal/inject/SingleValueInserter.java b/core-client/src/main/java/org/glassfish/jersey/client/internal/inject/SingleValueInserter.java
new file mode 100644
index 0000000..2ec9640
--- /dev/null
+++ b/core-client/src/main/java/org/glassfish/jersey/client/internal/inject/SingleValueInserter.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2010, 2017 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Payara Foundation and/or its affiliates.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.client.internal.inject;
+
+import javax.ws.rs.ProcessingException;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.ext.ParamConverter;
+import org.glassfish.jersey.internal.inject.InserterException;
+import org.glassfish.jersey.client.inject.ParameterInserter;
+
+
+/**
+ * Insert value of the parameter using a single parameter value and the underlying
+ * {@link ParamConverter param converter}.
+ *
+ * @param <T> custom Java type.
+ * @author Paul Sandoz
+ * @author Marek Potociar (marek.potociar at oracle.com)
+ * @author Gaurav Gupta (gaurav.gupta@payara.fish)
+ */
+final class SingleValueInserter<T> extends AbstractParamValueInserter<T> implements ParameterInserter<T, String> {
+
+    /**
+     * Create new single value inserter.
+     *
+     * @param converter          string value reader.
+     * @param parameterName      string parameter name.
+     * @param defaultValue       default value.
+     */
+    public SingleValueInserter(final ParamConverter<T> converter, final String parameterName, final String defaultValue) {
+        super(converter, parameterName, defaultValue);
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p/>
+     * This implementation inserts the value of the parameter applying the underlying
+     * {@link ParamConverter param converter} to the first value found in the list of potential multiple
+     * parameter values. Any other values in the multi-value list will be ignored.
+     *
+     * @param parameters map of parameters.
+     * @return inserted single parameter value.
+     */
+    @Override
+    public String insert(final T value){
+        try {
+            if (value == null && isDefaultValueRegistered()) {
+                return getDefaultValueString();
+            } else {
+                return toString(value);
+            }
+        } catch (final WebApplicationException | ProcessingException ex) {
+            throw ex;
+        } catch (final IllegalArgumentException ex) {
+            return defaultValue();
+        } catch (final Exception ex) {
+            throw new InserterException(ex);
+        }
+    }
+}
diff --git a/core-client/src/main/resources/org/glassfish/jersey/client/internal/localization.properties b/core-client/src/main/resources/org/glassfish/jersey/client/internal/localization.properties
index 7e45210..43db86d 100644
--- a/core-client/src/main/resources/org/glassfish/jersey/client/internal/localization.properties
+++ b/core-client/src/main/resources/org/glassfish/jersey/client/internal/localization.properties
@@ -33,12 +33,14 @@
 client.uri.template.null=URI template of the newly created target must not be null.
 client.uri.null=URI of the newly created target must not be null.
 client.uri.builder.null=URI builder of the newly created target must not be null.
+collection.inserter.type.unsupported=Unsupported collection type.
 digest.filter.qop.unsupported=The 'qop' (quality of protection) = {0} extension requested by the server is not supported by Jersey HttpDigestAuthFilter. Cannot authenticate against the server using Http Digest Authentication.
 error.closing.output.stream=Error when closing the output stream.
 error.committing.output.stream=Error while committing the request output stream.
 error.digest.filter.generator=Error during initialization of random generator of Digest authentication.
 error.http.method.entity.not.null=Entity must be null for http method {0}.
 error.http.method.entity.null=Entity must not be null for http method {0}.
+error.parameter.type.processing=Could not process parameter type {0}.
 error.service.locator.provider.instance.request=Incorrect type of request instance {0}. Parameter must be a default Jersey ClientRequestContext implementation.
 error.service.locator.provider.instance.response=Incorrect type of response instance {0}. Parameter must be a default Jersey ClientResponseContext implementation.
 ignored.async.threadpool.size=Zero or negative asynchronous thread pool size specified in the client configuration property: [{0}] \
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/inject/InserterException.java b/core-common/src/main/java/org/glassfish/jersey/internal/inject/InserterException.java
new file mode 100644
index 0000000..da80cca
--- /dev/null
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/inject/InserterException.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2010, 2017 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Payara Foundation and/or its affiliates.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.internal.inject;
+
+import javax.ws.rs.ProcessingException;
+import javax.ws.rs.WebApplicationException;
+
+/**
+ * A runtime exception that contains a cause, a checked or runtime exception,
+ * that may be passed to the cause of a {@link WebApplicationException}.
+ *
+ * @author Paul Sandoz
+ * @author Gaurav Gupta
+ *
+ */
+public class InserterException extends ProcessingException {
+    private static final long serialVersionUID = -4918023257104413981L;
+
+    /**
+     * Create new parameter extractor exception.
+     *
+     * @param message exception message.
+     */
+    public InserterException(String message) {
+        super(message);
+    }
+
+    /**
+     * Create new parameter extractor exception.
+     *
+     * @param message exception message.
+     * @param cause   exception cause.
+     */
+    public InserterException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Create new parameter extractor exception.
+     *
+     * @param cause exception cause.
+     */
+    public InserterException(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/ParamConverterConfigurator.java b/core-common/src/main/java/org/glassfish/jersey/internal/inject/ParamConverterConfigurator.java
similarity index 86%
rename from core-server/src/main/java/org/glassfish/jersey/server/internal/inject/ParamConverterConfigurator.java
rename to core-common/src/main/java/org/glassfish/jersey/internal/inject/ParamConverterConfigurator.java
index 29f97e4..477d918 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/ParamConverterConfigurator.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/inject/ParamConverterConfigurator.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Payara Foundation and/or its affiliates.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -14,15 +15,12 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.server.internal.inject;
+package org.glassfish.jersey.internal.inject;
 
 import javax.ws.rs.ext.ParamConverterProvider;
 
 import org.glassfish.jersey.internal.BootstrapBag;
 import org.glassfish.jersey.internal.BootstrapConfigurator;
-import org.glassfish.jersey.internal.inject.Bindings;
-import org.glassfish.jersey.internal.inject.InjectionManager;
-import org.glassfish.jersey.internal.inject.InstanceBinding;
 
 /**
  * Configurator which initializes and register {@link ParamConverters.AggregatedProvider} instances into {@link InjectionManager}.
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/ParamConverterFactory.java b/core-common/src/main/java/org/glassfish/jersey/internal/inject/ParamConverterFactory.java
similarity index 91%
rename from core-server/src/main/java/org/glassfish/jersey/server/internal/inject/ParamConverterFactory.java
rename to core-common/src/main/java/org/glassfish/jersey/internal/inject/ParamConverterFactory.java
index 2d8afd0..c29091d 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/ParamConverterFactory.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/inject/ParamConverterFactory.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Payara Foundation and/or its affiliates.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -14,7 +15,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.server.internal.inject;
+package org.glassfish.jersey.internal.inject;
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
@@ -22,12 +23,10 @@
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
-
+import javax.inject.Singleton;
 import javax.ws.rs.ext.ParamConverter;
 import javax.ws.rs.ext.ParamConverterProvider;
 
-import javax.inject.Singleton;
-
 /**
  * An aggregate {@link ParamConverterProvider param converter provider} that loads all
  * the registered {@link ParamConverterProvider} implementations.
@@ -42,12 +41,13 @@
  * @author Marek Potociar (marek.potociar at oracle.com)
  * @author Miroslav Fuksa
  */
+
 @Singleton
 public class ParamConverterFactory implements ParamConverterProvider {
 
     private final List<ParamConverterProvider> converterProviders;
 
-    ParamConverterFactory(Set<ParamConverterProvider> providers, Set<ParamConverterProvider> customProviders) {
+    public ParamConverterFactory(Set<ParamConverterProvider> providers, Set<ParamConverterProvider> customProviders) {
 
         Set<ParamConverterProvider> copyProviders = new LinkedHashSet<>(providers);
         converterProviders = new ArrayList<>();
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/ParamConverters.java b/core-common/src/main/java/org/glassfish/jersey/internal/inject/ParamConverters.java
similarity index 97%
rename from core-server/src/main/java/org/glassfish/jersey/server/internal/inject/ParamConverters.java
rename to core-common/src/main/java/org/glassfish/jersey/internal/inject/ParamConverters.java
index f7ac194..7d5a953 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/ParamConverters.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/inject/ParamConverters.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Payara Foundation and/or its affiliates.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -14,7 +15,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.server.internal.inject;
+package org.glassfish.jersey.internal.inject;
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Constructor;
@@ -32,10 +33,9 @@
 
 import javax.inject.Singleton;
 
-import org.glassfish.jersey.internal.inject.ExtractorException;
 import org.glassfish.jersey.internal.util.ReflectionHelper;
 import org.glassfish.jersey.message.internal.HttpDateFormat;
-import org.glassfish.jersey.server.internal.LocalizationMessages;
+import org.glassfish.jersey.internal.LocalizationMessages;
 
 /**
  * Container of several different {@link ParamConverterProvider param converter providers}
@@ -46,7 +46,7 @@
  * @author Marek Potociar (marek.potociar at oracle.com)
  */
 @Singleton
-class ParamConverters {
+public class ParamConverters {
 
     private abstract static class AbstractStringReader<T> implements ParamConverter<T> {
 
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/PrimitiveMapper.java b/core-common/src/main/java/org/glassfish/jersey/internal/inject/PrimitiveMapper.java
similarity index 89%
rename from core-server/src/main/java/org/glassfish/jersey/server/internal/inject/PrimitiveMapper.java
rename to core-common/src/main/java/org/glassfish/jersey/internal/inject/PrimitiveMapper.java
index eb9ce14..b763cc4 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/PrimitiveMapper.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/inject/PrimitiveMapper.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Payara Foundation and/or its affiliates.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -14,7 +15,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.server.internal.inject;
+package org.glassfish.jersey.internal.inject;
 
 import java.util.Collections;
 import java.util.Map;
@@ -27,11 +28,11 @@
  * @author Paul Sandoz
  * @author Marek Potociar (marek.potociar at oracle.com)
  */
-final class PrimitiveMapper {
+public final class PrimitiveMapper {
 
-    static final Map<Class, Class> primitiveToClassMap =
+    public static final Map<Class, Class> primitiveToClassMap =
             getPrimitiveToClassMap();
-    static final Map<Class, Object> primitiveToDefaultValueMap =
+    public static final Map<Class, Object> primitiveToDefaultValueMap =
             getPrimitiveToDefaultValueMap();
 
     private static Map<Class, Class> getPrimitiveToClassMap() {
diff --git a/core-common/src/main/resources/org/glassfish/jersey/internal/localization.properties b/core-common/src/main/resources/org/glassfish/jersey/internal/localization.properties
index 9ae4604..e7abfd8 100644
--- a/core-common/src/main/resources/org/glassfish/jersey/internal/localization.properties
+++ b/core-common/src/main/resources/org/glassfish/jersey/internal/localization.properties
@@ -1,5 +1,6 @@
 #
 # Copyright (c) 2012, 2019 Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2018 Payara Foundation and/or its affiliates.
 #
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License v. 2.0, which is available at
@@ -47,6 +48,7 @@
 error.newcookie.expires=NewCookie Expires header value ({0}) cannot be read.
 error.notfound.messagebodywriter=MessageBodyWriter not found for media type={0}, type={1}, genericType={2}.
 error.notfound.messagebodyreader=MessageBodyReader not found for media type={0}, type={1}, genericType={2}.
+error.parameter.invalid.char.value=Value "{0}" is not a character.
 error.parsing.entity.tag=Error parsing entity tag: {0}
 error.provider.constrainedTo.wrong.package=A registered provider {0} is constrained (via @ConstrainedTo) to {1} runtime but does not implement any provider interface usable in the runtime.
 error.provider.constrainedTo.wrong.runtime=A provider {0} registered in {2} runtime is constrained (via @ConstrainedTo) to {1} runtime.
@@ -108,6 +110,7 @@
 message.content.input.stream.close.failed=Error closing message content input stream.
 message.content.buffer.reset.failed=Error resetting the buffered message content input stream.
 method.not.getter.nor.setter=Method is neither getter nor setter.
+method.parameter.cannot.be.null=Method parameter "{0}" cannot be null.
 multiple.matching.constructors.found=Found {0} constructors with {1} parameters in {2} class. Selecting the first found constructor: {3}
 new.cookie.is.null=New cookie is null.
 no.container.available=No container available.
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/ApplicationHandler.java b/core-server/src/main/java/org/glassfish/jersey/server/ApplicationHandler.java
index 6e9449a..8f1b285 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/ApplicationHandler.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/ApplicationHandler.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2011, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Payara Foundation and/or its affiliates.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -75,7 +76,7 @@
 import org.glassfish.jersey.server.internal.JerseyRequestTimeoutHandler;
 import org.glassfish.jersey.server.internal.LocalizationMessages;
 import org.glassfish.jersey.server.internal.ProcessingProviders;
-import org.glassfish.jersey.server.internal.inject.ParamConverterConfigurator;
+import org.glassfish.jersey.internal.inject.ParamConverterConfigurator;
 import org.glassfish.jersey.server.internal.inject.ParamExtractorConfigurator;
 import org.glassfish.jersey.server.internal.inject.ValueParamProviderConfigurator;
 import org.glassfish.jersey.server.internal.monitoring.ApplicationEventImpl;
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/MultivaluedParameterExtractorFactory.java b/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/MultivaluedParameterExtractorFactory.java
index 4239036..efd153a 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/MultivaluedParameterExtractorFactory.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/MultivaluedParameterExtractorFactory.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Payara Foundation and/or its affiliates.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -30,11 +31,13 @@
 import javax.inject.Singleton;
 
 import org.glassfish.jersey.internal.inject.ExtractorException;
+import org.glassfish.jersey.internal.inject.ParamConverterFactory;
 import org.glassfish.jersey.internal.util.ReflectionHelper;
 import org.glassfish.jersey.internal.util.collection.ClassTypePair;
 import org.glassfish.jersey.internal.util.collection.LazyValue;
 import org.glassfish.jersey.server.internal.LocalizationMessages;
-import org.glassfish.jersey.server.model.Parameter;
+import org.glassfish.jersey.model.Parameter;
+import org.glassfish.jersey.internal.inject.PrimitiveMapper;
 
 /**
  * Implementation of {@link MultivaluedParameterExtractorProvider}. For each
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/MultivaluedParameterExtractorProvider.java b/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/MultivaluedParameterExtractorProvider.java
index cf8b7af..0aabeaf 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/MultivaluedParameterExtractorProvider.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/MultivaluedParameterExtractorProvider.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Payara Foundation and/or its affiliates.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -16,7 +17,7 @@
 
 package org.glassfish.jersey.server.internal.inject;
 
-import org.glassfish.jersey.server.model.Parameter;
+import org.glassfish.jersey.model.Parameter;
 
 /**
  * Provider of multivalued parameter extractors.
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/ParamExtractorConfigurator.java b/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/ParamExtractorConfigurator.java
index 7d56f88..ca674d0 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/ParamExtractorConfigurator.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/ParamExtractorConfigurator.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Payara Foundation and/or its affiliates.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -22,6 +23,7 @@
 import org.glassfish.jersey.internal.BootstrapConfigurator;
 import org.glassfish.jersey.internal.inject.Bindings;
 import org.glassfish.jersey.internal.inject.InjectionManager;
+import org.glassfish.jersey.internal.inject.ParamConverterFactory;
 import org.glassfish.jersey.internal.inject.Providers;
 import org.glassfish.jersey.internal.util.collection.LazyValue;
 import org.glassfish.jersey.internal.util.collection.Value;
diff --git a/core-server/src/test/java/org/glassfish/jersey/server/TestInjectionManagerFactory.java b/core-server/src/test/java/org/glassfish/jersey/server/TestInjectionManagerFactory.java
index fed2888..204b9d0 100644
--- a/core-server/src/test/java/org/glassfish/jersey/server/TestInjectionManagerFactory.java
+++ b/core-server/src/test/java/org/glassfish/jersey/server/TestInjectionManagerFactory.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Payara Foundation and/or its affiliates.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -33,7 +34,7 @@
 import org.glassfish.jersey.message.internal.MessagingBinders;
 import org.glassfish.jersey.model.internal.ManagedObjectsFinalizer;
 import org.glassfish.jersey.process.internal.RequestScope;
-import org.glassfish.jersey.server.internal.inject.ParamConverterConfigurator;
+import org.glassfish.jersey.internal.inject.ParamConverterConfigurator;
 import org.glassfish.jersey.server.internal.inject.ParamExtractorConfigurator;
 import org.glassfish.jersey.server.internal.inject.ValueParamProviderConfigurator;
 import org.glassfish.jersey.server.internal.process.RequestProcessingConfigurator;
diff --git a/core-server/src/test/java/org/glassfish/jersey/server/internal/inject/ParamConverterInternalTest.java b/core-server/src/test/java/org/glassfish/jersey/server/internal/inject/ParamConverterInternalTest.java
index 9b4c393..cf69fb7 100644
--- a/core-server/src/test/java/org/glassfish/jersey/server/internal/inject/ParamConverterInternalTest.java
+++ b/core-server/src/test/java/org/glassfish/jersey/server/internal/inject/ParamConverterInternalTest.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Payara Foundation and/or its affiliates.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -39,6 +40,7 @@
 import javax.ws.rs.ext.ParamConverterProvider;
 
 import org.glassfish.jersey.internal.inject.ExtractorException;
+import org.glassfish.jersey.internal.inject.ParamConverters;
 import org.glassfish.jersey.internal.util.ReflectionHelper;
 import org.glassfish.jersey.internal.util.collection.ClassTypePair;
 import org.glassfish.jersey.server.ApplicationHandler;