/**
* <p>
* Provides transforming collections.
* </p>
* <h2>Overview</h2>
* <p>
* A transforming collection is essentially a decorator of an existing collection which transforms the collection's
* elements from one type to another. Note that all such classes are views! They operate on the wrapped collection and
* all changes to either of them is reflected in the other.
* <p>
* The decorated collection is usually referred to as the <i>inner collection</i> and it's generic type accordingly as
* the <i>inner type</i>. The transforming collection and its generic type are referred to as <i>outer collection</i>
* and <i>outer type</i>, respectively.
* </p>
* <h2>Details</h2>
* <p>
* The following details are important to use transforming collections without unexpected problems.
* </p>
* <h3>Forwarding</h3>
* <p>
* Unless otherwise noted the views forward all method calls (of abstract and default methods existing in JDK 8) to
* <b>the same method</b> on the inner collection. This implies that all guarantees made by such methods (e.g. regarding
* atomicity) are upheld by the transformation.
* </p>
* <h3>Transformation</h3>
* <p>
* The transformation is computed with a pair of functions. One is used to transform outer elements to inner elements
* and another one for the other direction. In the case of a {@link java.util.Map Map} two such pairs exist: one for
* keys and one for values.
* <p>
* The transforming functions must be inverse to each other with regard to {@link java.lang.Object#equals(Object)
* equals}, i.e. {@code outer.equals(toOuter(toInner(outer))} and {@code inner.equals(toInner(toOuter(inner))} must be
* true for all {@code outer} and {@code inner} elements. If this is not the case, the collections might behave in an
* unpredictable manner.
* <p>
* Note that the same is not true for identity, i.e. {@code outer == toOuter(toInner(outer))} may be false. It is
* explicitly allowed to create new outer elements from inner elements and vice versa. This means that outer elements
* may have no meaningful identity. E.g. on adding an outer instance {@code outerOrg} it can be transformed to
* {@code inner} and on access back to {@code outer}. Whether {@code outerOrg == outer} holds, depends on the
* transformation functions and is generally unspecified - it might never, sometimes or always be true. Transforming
* collections might give more details on their behavior regarding this.
* <p>
* A special case of transformation occurs when the inner and outer type have a type relationship. This can shortcut one
* of the transformations to the identity, i.e. because an instance of one type is also of the other type the
* corresponding transformation can simply return the instance itself. This makes the collection "leak" elements of the
* wrong type. If the suptype does not fully obey the <a
* href="https://en.wikipedia.org/wiki/Liskov_substitution_principle">Liskov Substitution Principle</a> this can lead to
* unexpected behavior.
* <p>
* Transforming functions should have no side effects. No guarantees are made regarding how often transformations are
* called.
* </p>
* <h3>Type Safety</h3>
* <p>
* All operations on transforming collections are type safe in the usual static, compile-time way. But since many
* methods from the collection interfaces allow {@link java.lang.Object Object}s (e.g
* {@link java.util.Collection#contains(Object) Collection.contains(Object)}) or collections of unknown generic type
* (e.g {@link java.util.Collection#addAll(java.util.Collection) Collection.addAll(Collection<?>)}) as arguments,
* this does not cover all cases which can occur at runtime.
* <p>
* If one of those methods is called with a type which does not match the transforming collection's outer type the
* method may throw a {@link java.lang.ClassCastException ClassCastException}. While this is in accordance with the
* methods' contracts it might still be unexpected.
* <p>
* One way to circumvent this to pay close attention when using the collection and ensuring that such calls can not
* occur (which is often easy). Another way is to write wrappers which catch and silently ignore the exception.
* </p>
* <h2>Similar Features From Other Libraries</h2>
* <p>
* To my (<a href="http://blog.codefx.org/about-nicolai-parlog/">nipa</a>'s) knowledge two other libraries offer similar
* functionality, namely <a href="http://commons.apache.org/proper/commons-collections/">Apache Commons Collections</a>
* and <a href="https://github.com/google/guava">Google Guava</a>. Both have shortcomings which this implementation aims
* to overcome.
* </p>
* <h3>Apache Commons Collections</h3>
* <p>
* Commons provides the <a href=
* "https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/collection/TransformedCollection.html"
* > {@code TransformedCollection}</a>. It only affects add methods,
* "thus objects must be removed or searched for using their transformed form." The implementations in this package
* suffer from no such limitation.
* </p>
* <h3>Google Guava</h3>
* <p>
* Guava contains a utility method <a href=
* "http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Lists.html#transform%28java.util.List,%20com.google.common.base.Function%29"
* >{@code transform(List, Function)}</a> which returns a transformed view of the specified map. But
* "the transform is one-way and new items cannot be stored in the returned list." The implementations in this package
* explicitly allow editing both instances.
* </p>
*/
package org.codefx.libfx.collection.transform;