// Path: net/src/main/java/hm/binkley/net/http/HttpUrlExtensions.java
// @EqualsAndHashCode
// public static final class PathSegment {
//     private static final Pattern semicolon = compile(";");
//     private static final Pattern equals = compile("=");
//     private static final Pattern comma = compile(",");
// 
//     private final int position;
//     private final String name;
//     private final Map<String, List<String>> parameters;
// 
//     /** Package scope for testing. */
//     PathSegment(final int position, final String name,
//             final Map<String, List<String>> parameters) {
//         this.position = position;
//         this.name = name;
//         this.parameters = parameters;
//     }
// 
//     private PathSegment(final int position, final String segment) {
//         this.position = position;
// 
//         final String[] pathAndPairs = makePathAndPairs(segment);
//         if (0 == pathAndPairs.length) {
//             name = segment;
//             parameters = emptyMap();
//             return;
//         }
//         name = pathOf(pathAndPairs);
// 
//         final Map<String, List<String>> parameters
//                 = new LinkedHashMap<>();
//         for (int i = 1; i < pathAndPairs.length; ++i) {
//             final String[] pair = makePair(pathAndPairs[i]);
//             final List<String> previous = previousValues(parameters,
//                     pair);
//             addValues(previous, valuesOrNull(pair));
//         }
//         unmodifiableValues(parameters);
//         this.parameters = unmodifiableMap(parameters);
//     }
// 
//     /** The position of this path segment in the URL, 0-based. */
//     @Nonnegative
//     public int position() {
//         return position;
//     }
// 
//     /** The "name" or path component of this segment in the URL. */
//     @Nonnull
//     public String name() {
//         return name;
//     }
// 
//     /**
//      * The unmodifiable map of path parameters for this path segment,
//      * iterable in the same order as the path segments appear in the URL.
//      * Similarly, path parameters iterate in their order of appearance.
//      */
//     @Nonnull
//     public Map<String, List<String>> params() {
//         return parameters;
//     }
// 
//     @Override
//     public String toString() {
//         return format("[%d]%s=%s", position, name, parameters);
//     }
// 
//     @Nonnull
//     private static String[] makePathAndPairs(final String segment) {
//         return semicolon.split(segment, -1);
//     }
// 
//     @Nonnull
//     private static String pathOf(final String[] pathAndPairs) {
//         return pathAndPairs[0];
//     }
// 
//     @Nonnull
//     private static String[] makePair(final String pair) {
//         return equals.split(pair, 2);
//     }
// 
//     @Nonnull
//     private static String keyOf(final String[] key) {
//         return key[0];
//     }
// 
//     @Nullable
//     private static List<String> valuesOrNull(final String[] v) {
//         return 2 == v.length ? asList(comma.split(v[1])) : null;
//     }
// 
//     @Nonnull
//     private static List<String> previousValues(
//             final Map<String, List<String>> parameters,
//             final String[] pair) {
//         return parameters.
//                 computeIfAbsent(keyOf(pair), k -> new ArrayList<>());
//     }
// 
//     private static void addValues(final List<String> previousValues,
//             final List<String> pairValues) {
//         if (null == pairValues)
//             previousValues.add(null);
//         else
//             previousValues.addAll(pairValues);
//     }
// 
//     private static void unmodifiableValues(
//             final Map<String, List<String>> parameters) {
//         for (final Entry<String, List<String>> e : parameters.entrySet())
//             e.setValue(unmodifiableList(e.getValue()));
//     }
// }


import com.squareup.okhttp.HttpUrl;
import hm.binkley.net.http.HttpUrlExtensions.PathSegment;
import lombok.experimental.ExtensionMethod;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonMap;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
package hm.binkley.net.http;




/**
 * {@code HttpUrlExtensionsTest} tests {@link HttpUrlExtensions}.
 *
 * @author <a href="mailto:binkley@alumni.rice.edu">B. K. Oxley (binkley)</a>
 */
@RunWith(Parameterized.class)
public class HttpUrlExtensionsTest {
    private static final PathSegment emptyRoot = new PathSegment(0, "",
            emptyMap());

    @Parameter(0)
    public String url;
    @Parameter(1)
    public List<PathSegment> paths;
    @Parameter(2)
    public Map<String, List<String>> queries;

    @Parameters(name = "{index}: {0} -> {1} ; {2}")
    public static Collection<Object[]> parameters() {
        return asList(args("http://foo/", emptyMap(), emptyRoot),
                args("http://foo/bar", emptyMap(),
                        new PathSegment(0, "bar", emptyMap())),
                args("http://foo/?a&a", singletonMap("a", asList(null, null)),
                        emptyRoot));
    }

    @Test
// Path: net/src/main/java/hm/binkley/net/http/HttpUrlExtensions.java
// @EqualsAndHashCode
// public static final class PathSegment {
//     private static final Pattern semicolon = compile(";");
//     private static final Pattern equals = compile("=");
//     private static final Pattern comma = compile(",");
// 
//     private final int position;
//     private final String name;
//     private final Map<String, List<String>> parameters;
// 
//     /** Package scope for testing. */
//     PathSegment(final int position, final String name,
//             final Map<String, List<String>> parameters) {
//         this.position = position;
//         this.name = name;
//         this.parameters = parameters;
//     }
// 
//     private PathSegment(final int position, final String segment) {
//         this.position = position;
// 
//         final String[] pathAndPairs = makePathAndPairs(segment);
//         if (0 == pathAndPairs.length) {
//             name = segment;
//             parameters = emptyMap();
//             return;
//         }
//         name = pathOf(pathAndPairs);
// 
//         final Map<String, List<String>> parameters
//                 = new LinkedHashMap<>();
//         for (int i = 1; i < pathAndPairs.length; ++i) {
//             final String[] pair = makePair(pathAndPairs[i]);
//             final List<String> previous = previousValues(parameters,
//                     pair);
//             addValues(previous, valuesOrNull(pair));
//         }
//         unmodifiableValues(parameters);
//         this.parameters = unmodifiableMap(parameters);
//     }
// 
//     /** The position of this path segment in the URL, 0-based. */
//     @Nonnegative
//     public int position() {
//         return position;
//     }
// 
//     /** The "name" or path component of this segment in the URL. */
//     @Nonnull
//     public String name() {
//         return name;
//     }
// 
//     /**
//      * The unmodifiable map of path parameters for this path segment,
//      * iterable in the same order as the path segments appear in the URL.
//      * Similarly, path parameters iterate in their order of appearance.
//      */
//     @Nonnull
//     public Map<String, List<String>> params() {
//         return parameters;
//     }
// 
//     @Override
//     public String toString() {
//         return format("[%d]%s=%s", position, name, parameters);
//     }
// 
//     @Nonnull
//     private static String[] makePathAndPairs(final String segment) {
//         return semicolon.split(segment, -1);
//     }
// 
//     @Nonnull
//     private static String pathOf(final String[] pathAndPairs) {
//         return pathAndPairs[0];
//     }
// 
//     @Nonnull
//     private static String[] makePair(final String pair) {
//         return equals.split(pair, 2);
//     }
// 
//     @Nonnull
//     private static String keyOf(final String[] key) {
//         return key[0];
//     }
// 
//     @Nullable
//     private static List<String> valuesOrNull(final String[] v) {
//         return 2 == v.length ? asList(comma.split(v[1])) : null;
//     }
// 
//     @Nonnull
//     private static List<String> previousValues(
//             final Map<String, List<String>> parameters,
//             final String[] pair) {
//         return parameters.
//                 computeIfAbsent(keyOf(pair), k -> new ArrayList<>());
//     }
// 
//     private static void addValues(final List<String> previousValues,
//             final List<String> pairValues) {
//         if (null == pairValues)
//             previousValues.add(null);
//         else
//             previousValues.addAll(pairValues);
//     }
// 
//     private static void unmodifiableValues(
//             final Map<String, List<String>> parameters) {
//         for (final Entry<String, List<String>> e : parameters.entrySet())
//             e.setValue(unmodifiableList(e.getValue()));
//     }
// }


// Path: net/src/test/java/hm/binkley/net/http/HttpUrlExtensionsTest.java
import com.squareup.okhttp.HttpUrl;
import hm.binkley.net.http.HttpUrlExtensions.PathSegment;
import lombok.experimental.ExtensionMethod;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonMap;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

package hm.binkley.net.http;




/**
 * {@code HttpUrlExtensionsTest} tests {@link HttpUrlExtensions}.
 *
 * @author <a href="mailto:binkley@alumni.rice.edu">B. K. Oxley (binkley)</a>
 */
@RunWith(Parameterized.class)
public class HttpUrlExtensionsTest {
    private static final PathSegment emptyRoot = new PathSegment(0, "",
            emptyMap());

    @Parameter(0)
    public String url;
    @Parameter(1)
    public List<PathSegment> paths;
    @Parameter(2)
    public Map<String, List<String>> queries;

    @Parameters(name = "{index}: {0} -> {1} ; {2}")
    public static Collection<Object[]> parameters() {
        return asList(args("http://foo/", emptyMap(), emptyRoot),
                args("http://foo/bar", emptyMap(),
                        new PathSegment(0, "bar", emptyMap())),
                args("http://foo/?a&a", singletonMap("a", asList(null, null)),
                        emptyRoot));
    }

    @Test
    public void shouldParseUrl() {