// Path: public-api/src/main/java/info/rolandkrueger/userservice/api/_internal/model/AbstractBaseApiData.java
// public abstract class AbstractBaseApiData<R extends AbstractResource> {
//     private Collection<Link> links;
// 
//     /**
//      * Creates a new resource object for this data type. The method uses the self link to create the resource.
//      *
//      * @param self link to the resource
//      * @return a new resource object that represents this data type on the server side
//      * @see #getSelf()
//      */
//     protected abstract R createNewResource(Link self);
// 
//     /**
//      * Provides a collection of all resource links that could be read from the resource. These links lead to related
//      * resources and can be used to create new instances of subclasses of {@link AbstractResource} or
//      * {@link info.rolandkrueger.userservice.api._internal.AbstractPagedResource}.
//      *
//      * @return the collection of resource links
//      */
//     public final Collection<Link> getLinks() {
//         return links;
//     }
// 
//     /**
//      * Sets the list of the available links to related resources. Will be called by the JSON unmarshaller.
//      *
//      * @param links collection of resource links
//      */
//     public final void setLinks(Collection<Link> links) {
//         this.links = links;
//     }
// 
//     /**
//      * Provides the link to self.
//      *
//      * @return the self link
//      */
//     public final Link getSelf() {
//         return links == null ? null : links.iterator().next();
//     }
// 
//     /**
//      * Provides the resource object that corresponds to this data type.
//      * <p/>
//      * Creates a new instance of {@link <R>} on every invocation. Is ignored by the JSON processor when transferring an
//      * {@link AbstractBaseApiData} to the server.
//      *
//      * @return a new instance of a corresponding sub-class of {@link AbstractResource} for this data type.
//      */
//     @JsonIgnore
//     public final R getResource() {
//         R resource = createNewResource(getSelf());
//         return resource;
//     }
// }
// 
// Path: public-api/src/main/java/info/rolandkrueger/userservice/api/enums/SortDirection.java
// public enum SortDirection {
//     ASC, DESC;
// }


import com.google.common.base.Joiner;
import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import info.rolandkrueger.userservice.api._internal.model.AbstractBaseApiData;
import info.rolandkrueger.userservice.api.enums.SortDirection;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.PagedResources;
import org.springframework.hateoas.Resources;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestClientException;
import java.util.Collection;
import java.util.HashMap;
package info.rolandkrueger.userservice.api._internal;



/**
 * A REST collection resource that allows to page through the list of entities. This class adds methods to the general
 * {@link AbstractResource} interface supporting paging and sorting the collection resource's data.
 * <p/>
 * When you create a sub-class for this paged resource then parameter T denotes the data type represented by the resource,
 * and parameter R is the subclass itself. E. g., if you have a domain type <code>Person</code> and a corresponding
 * client-side data type <code>PersonApiData</code> then a paged <code>Person</code> paged resource could have the following
 * signature:
 * <p/>
 * <code>
 * public class PersonsResource extends AbstractPagedResource&lt;PersonApiData, PersonPagedResource&gt; {...}
 * </code>
 *
 * @param <T> type of the data object represented by this collection resource
 * @param <R> type of the sub-class inheriting from this resource
 * @author Roland Krüger
 * @see AbstractBaseApiData
 */
public abstract class AbstractPagedResource<T extends AbstractBaseApiData<?>, R extends AbstractPagedResource> extends AbstractResource<T> {
    /**
     * Response entity object for this collection resource.
     */
    private ResponseEntity<PagedResources<T>> responseEntity;

    /**
     * {@inheritDoc}
     */
    protected AbstractPagedResource(Link templatedSelfLink, Link self) {
        super(templatedSelfLink, self);
    }

    /**
     * Factory method for creating a new instance of this resource. Has to be implemented by sub-classes in such a way
     * that this implementation returns a new instance of the implementing class for the given self link.
     *
     * @param self link to self to be used by the created resource object
     * @return a new instance of the implementing sub-class
     */
    protected abstract R createResourceInstance(Link self);

    /**
     * Sets the templated link to self for this resource.
     */
    protected final void setTemplatedSelfLink(Link templatedSelfLink) {
        this.templatedSelfLink = templatedSelfLink;
    }

    /**
     * Configures this resource to return its data as a sorted list for a given page with a given size. This method
     * returns a new paged resource object with its self link parameterized to sort by the specified property and to
     * return the specified page. This method will only create a parameterized resource object and will not yet call
     * the service to fetch the data.
     *
     * @param page           requested page number
     * @param size           requested page size
     * @param sortByProperty sort property, has to be a valid property name of the resource's data type
     * @param direction      sort direction: ascending or descending
     * @return a new paged resource object with its self link parameterized to sort by the specified parameters limited by
     * the specified page
     */
// Path: public-api/src/main/java/info/rolandkrueger/userservice/api/_internal/model/AbstractBaseApiData.java
// public abstract class AbstractBaseApiData<R extends AbstractResource> {
//     private Collection<Link> links;
// 
//     /**
//      * Creates a new resource object for this data type. The method uses the self link to create the resource.
//      *
//      * @param self link to the resource
//      * @return a new resource object that represents this data type on the server side
//      * @see #getSelf()
//      */
//     protected abstract R createNewResource(Link self);
// 
//     /**
//      * Provides a collection of all resource links that could be read from the resource. These links lead to related
//      * resources and can be used to create new instances of subclasses of {@link AbstractResource} or
//      * {@link info.rolandkrueger.userservice.api._internal.AbstractPagedResource}.
//      *
//      * @return the collection of resource links
//      */
//     public final Collection<Link> getLinks() {
//         return links;
//     }
// 
//     /**
//      * Sets the list of the available links to related resources. Will be called by the JSON unmarshaller.
//      *
//      * @param links collection of resource links
//      */
//     public final void setLinks(Collection<Link> links) {
//         this.links = links;
//     }
// 
//     /**
//      * Provides the link to self.
//      *
//      * @return the self link
//      */
//     public final Link getSelf() {
//         return links == null ? null : links.iterator().next();
//     }
// 
//     /**
//      * Provides the resource object that corresponds to this data type.
//      * <p/>
//      * Creates a new instance of {@link <R>} on every invocation. Is ignored by the JSON processor when transferring an
//      * {@link AbstractBaseApiData} to the server.
//      *
//      * @return a new instance of a corresponding sub-class of {@link AbstractResource} for this data type.
//      */
//     @JsonIgnore
//     public final R getResource() {
//         R resource = createNewResource(getSelf());
//         return resource;
//     }
// }
// 
// Path: public-api/src/main/java/info/rolandkrueger/userservice/api/enums/SortDirection.java
// public enum SortDirection {
//     ASC, DESC;
// }


// Path: public-api/src/main/java/info/rolandkrueger/userservice/api/_internal/AbstractPagedResource.java
import com.google.common.base.Joiner;
import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import info.rolandkrueger.userservice.api._internal.model.AbstractBaseApiData;
import info.rolandkrueger.userservice.api.enums.SortDirection;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.PagedResources;
import org.springframework.hateoas.Resources;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestClientException;
import java.util.Collection;
import java.util.HashMap;

package info.rolandkrueger.userservice.api._internal;



/**
 * A REST collection resource that allows to page through the list of entities. This class adds methods to the general
 * {@link AbstractResource} interface supporting paging and sorting the collection resource's data.
 * <p/>
 * When you create a sub-class for this paged resource then parameter T denotes the data type represented by the resource,
 * and parameter R is the subclass itself. E. g., if you have a domain type <code>Person</code> and a corresponding
 * client-side data type <code>PersonApiData</code> then a paged <code>Person</code> paged resource could have the following
 * signature:
 * <p/>
 * <code>
 * public class PersonsResource extends AbstractPagedResource&lt;PersonApiData, PersonPagedResource&gt; {...}
 * </code>
 *
 * @param <T> type of the data object represented by this collection resource
 * @param <R> type of the sub-class inheriting from this resource
 * @author Roland Krüger
 * @see AbstractBaseApiData
 */
public abstract class AbstractPagedResource<T extends AbstractBaseApiData<?>, R extends AbstractPagedResource> extends AbstractResource<T> {
    /**
     * Response entity object for this collection resource.
     */
    private ResponseEntity<PagedResources<T>> responseEntity;

    /**
     * {@inheritDoc}
     */
    protected AbstractPagedResource(Link templatedSelfLink, Link self) {
        super(templatedSelfLink, self);
    }

    /**
     * Factory method for creating a new instance of this resource. Has to be implemented by sub-classes in such a way
     * that this implementation returns a new instance of the implementing class for the given self link.
     *
     * @param self link to self to be used by the created resource object
     * @return a new instance of the implementing sub-class
     */
    protected abstract R createResourceInstance(Link self);

    /**
     * Sets the templated link to self for this resource.
     */
    protected final void setTemplatedSelfLink(Link templatedSelfLink) {
        this.templatedSelfLink = templatedSelfLink;
    }

    /**
     * Configures this resource to return its data as a sorted list for a given page with a given size. This method
     * returns a new paged resource object with its self link parameterized to sort by the specified property and to
     * return the specified page. This method will only create a parameterized resource object and will not yet call
     * the service to fetch the data.
     *
     * @param page           requested page number
     * @param size           requested page size
     * @param sortByProperty sort property, has to be a valid property name of the resource's data type
     * @param direction      sort direction: ascending or descending
     * @return a new paged resource object with its self link parameterized to sort by the specified parameters limited by
     * the specified page
     */
    public final R goToPageSorted(Integer page, Integer size, String sortByProperty, SortDirection direction) {