// Path: src/main/java/de/otto/edison/hal/EmbeddedTypeInfo.java
// public static EmbeddedTypeInfo withEmbedded(final String rel,
//                                             final Class<? extends HalRepresentation> embeddedType,
//                                             final EmbeddedTypeInfo... nestedTypeInfo) {
//     if (nestedTypeInfo == null || nestedTypeInfo.length == 0) {
//         return new EmbeddedTypeInfo(rel, embeddedType, emptyList());
//     } else {
//         return new EmbeddedTypeInfo(rel, embeddedType, asList(nestedTypeInfo));
//     }
// }
// 
// Path: src/main/java/de/otto/edison/hal/HalParser.java
// public static HalParser parse(final String json) {
//     return new HalParser(json, DEFAULT_JSON_MAPPER);
// }
// 
// Path: src/main/java/de/otto/edison/hal/Link.java
// public static Builder copyOf(final Link prototype) {
//     return new Builder(prototype.rel, prototype.href)
//             .withType(prototype.type)
//             .withProfile(prototype.profile)
//             .withTitle(prototype.title)
//             .withName(prototype.name)
//             .withDeprecation(prototype.deprecation)
//             .withHrefLang(prototype.hreflang);
// }
// 
// Path: src/main/java/de/otto/edison/hal/Link.java
// public static Link self(final String href) {
//     return new Link("self", href);
// }
// 
// Path: src/main/java/de/otto/edison/hal/LinkPredicates.java
// public static Predicate<Link> always() {
//     return link -> true;
// }


import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonPointer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.otto.edison.hal.*;
import org.slf4j.Logger;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;
import static com.damnhandy.uri.template.UriTemplate.fromTemplate;
import static com.fasterxml.jackson.databind.DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY;
import static de.otto.edison.hal.EmbeddedTypeInfo.withEmbedded;
import static de.otto.edison.hal.HalParser.parse;
import static de.otto.edison.hal.Link.copyOf;
import static de.otto.edison.hal.Link.self;
import static de.otto.edison.hal.LinkPredicates.always;
import static java.lang.String.format;
import static java.util.Arrays.asList;
import static java.util.Collections.*;
import static java.util.Objects.requireNonNull;
import static org.slf4j.LoggerFactory.getLogger;
     * @since 2.0.0
     */
    public Traverson followLink(final String rel, 
                                final Map<String, Object> vars) {
        return followLink(rel, always(), vars);
    }

    /**
     * Follow the first {@link Link} of the current resource, selected by its link-relation type. The
     * {@link LinkPredicates predicate} is used to select the matching link, if multiple links per link-relation type
     * are available.
     * <p>
     *     Templated links are expanded to URIs using the specified template variables.
     * </p>
     * <p>
     *     If the current node has {@link Embedded embedded} items with the specified {@code rel},
     *     these items are used instead of resolving the associated {@link Link}.
     * </p>
     *
     * @param rel the link-relation type of the followed link
     * @param predicate the predicate used to select the link to follow.
     * @param vars uri-template variables used to build links.
     * @return this
     * @since 1.0.0
     */
    public Traverson follow(final String rel, 
                            final Predicate<Link> predicate, 
                            final Map<String, Object> vars) {
        checkState();
        hops.add(new Hop(rel, predicate, vars, false));
// Path: src/main/java/de/otto/edison/hal/EmbeddedTypeInfo.java
// public static EmbeddedTypeInfo withEmbedded(final String rel,
//                                             final Class<? extends HalRepresentation> embeddedType,
//                                             final EmbeddedTypeInfo... nestedTypeInfo) {
//     if (nestedTypeInfo == null || nestedTypeInfo.length == 0) {
//         return new EmbeddedTypeInfo(rel, embeddedType, emptyList());
//     } else {
//         return new EmbeddedTypeInfo(rel, embeddedType, asList(nestedTypeInfo));
//     }
// }
// 
// Path: src/main/java/de/otto/edison/hal/HalParser.java
// public static HalParser parse(final String json) {
//     return new HalParser(json, DEFAULT_JSON_MAPPER);
// }
// 
// Path: src/main/java/de/otto/edison/hal/Link.java
// public static Builder copyOf(final Link prototype) {
//     return new Builder(prototype.rel, prototype.href)
//             .withType(prototype.type)
//             .withProfile(prototype.profile)
//             .withTitle(prototype.title)
//             .withName(prototype.name)
//             .withDeprecation(prototype.deprecation)
//             .withHrefLang(prototype.hreflang);
// }
// 
// Path: src/main/java/de/otto/edison/hal/Link.java
// public static Link self(final String href) {
//     return new Link("self", href);
// }
// 
// Path: src/main/java/de/otto/edison/hal/LinkPredicates.java
// public static Predicate<Link> always() {
//     return link -> true;
// }


// Path: src/main/java/de/otto/edison/hal/traverson/Traverson.java
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonPointer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.otto.edison.hal.*;
import org.slf4j.Logger;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;
import static com.damnhandy.uri.template.UriTemplate.fromTemplate;
import static com.fasterxml.jackson.databind.DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY;
import static de.otto.edison.hal.EmbeddedTypeInfo.withEmbedded;
import static de.otto.edison.hal.HalParser.parse;
import static de.otto.edison.hal.Link.copyOf;
import static de.otto.edison.hal.Link.self;
import static de.otto.edison.hal.LinkPredicates.always;
import static java.lang.String.format;
import static java.util.Arrays.asList;
import static java.util.Collections.*;
import static java.util.Objects.requireNonNull;
import static org.slf4j.LoggerFactory.getLogger;

     * @since 2.0.0
     */
    public Traverson followLink(final String rel, 
                                final Map<String, Object> vars) {
        return followLink(rel, always(), vars);
    }

    /**
     * Follow the first {@link Link} of the current resource, selected by its link-relation type. The
     * {@link LinkPredicates predicate} is used to select the matching link, if multiple links per link-relation type
     * are available.
     * <p>
     *     Templated links are expanded to URIs using the specified template variables.
     * </p>
     * <p>
     *     If the current node has {@link Embedded embedded} items with the specified {@code rel},
     *     these items are used instead of resolving the associated {@link Link}.
     * </p>
     *
     * @param rel the link-relation type of the followed link
     * @param predicate the predicate used to select the link to follow.
     * @param vars uri-template variables used to build links.
     * @return this
     * @since 1.0.0
     */
    public Traverson follow(final String rel, 
                            final Predicate<Link> predicate, 
                            final Map<String, Object> vars) {
        checkState();
        hops.add(new Hop(rel, predicate, vars, false));
        return this;