anchor.diff:  
   == Introduction
   
  +While Ehcache is a Java cache, it cannot always store its mapping as Java objects.
  +
   The on-heap store is capable of storing cached objects either by reference (where the given key and value references
  -are stored) or by value (where a copy of the given key and value are made and those copies are then stored) while all
  -other stores are only capable of storing by value.
  -
  -Serializers and Copiers are the components that perform the required operations.
  +are stored) or by value (where a copy of the given key and value are made and those copies are then stored).
  +All other stores are only capable of storing a byte representation of the key/value pair.
  +
  +`Serializer` and `Copier` are the abstractions to enable these different storage options.
   
   === Serializers
   
  -All stores but the on-heap one need some form of serialization/deserialization of
  -objects to be able to store and retrieve them as they cannot internally store plain java objects but only bunch-of-bytes representations
  -of them. Serializers are the Ehcache mechanism that revolves this logic: every cache that has at least one store that
  -cannot store by reference is going to use a pair of Serializers: one for the key and another one for the value.
  -
  -Serializers are scoped at the cache level: a cache can have a serializer for its keys and another one for its values.
  -All stores of a cache will be using and sharing the same key and value serializer pair.
  +All stores but the on-heap one need some form of serialization/deserialization of objects to be able to store and retrieve mappings.
  +This is because they cannot internally store plain java objects but only bunch-of-bytes representations of them.
  +
  +`Serializer` is the Ehcache abstraction solving this: every cache that has at least one store that
  +cannot store by reference is going to use a pair of `Serializer`, one for the key and another one for the value.
  +
  +A `Serializer` is scoped at the cache level and all stores of a cache will be using and sharing the same serializer pair.
   
   ==== How is a serializer configured?
   
   There are two places where serializers can be configured:
   
  -- at the cache level where one can use `CacheConfigurationBuilder.withKeySerializer()` and `CacheConfigurationBuilder.withValueSerializer()`.
  -Both instances and class names can be configured.
  -- at the cache manager level where one can use `CacheManagerBuilder.withSerializer(Class clazz, Class serializer)`
  +* at the cache level where one can use
  +** `CacheConfigurationBuilder.withKeySerializer(Class<? extends Serializer<K>> keySerializerClass)`,
  +** `CacheConfigurationBuilder.withKeySerializer(Serializer<K> keySerializer)`,
  +** `CacheConfigurationBuilder.withValueSerializer(Class<? extends Serializer<V>> valueSerializerClass)`,
  +** and `CacheConfigurationBuilder.withValueSerializer(Serializer<V> valueSerializer)`
  ++
  +which allow by _instance_ or by _class name_ configuration.
  +* at the cache manager level where one can use
  +** `CacheManagerBuilder.withSerializer(Class<C> clazz, Class<? extends Serializer<C>> serializer)`
   
   If a serializer is configured directly at the cache level, it will be used, ignoring any cache manager level configuration.
   
   If a serializer is configured at the cache manager level, upon initialization, a cache with no specifically configured serializer will
  -search through its cache manager's registered list of serializers and try to find one that directly matches the cache's key or value type. If such
  -search fails, all the registered serializers will be tried in the added order to find one that handles compatible types.
  +search through its cache manager's registered list of serializers and try to find one that directly matches the cache's key or value type.
  +If such search fails, all the registered serializers will be tried in the added order to find one that handles compatible types.
   
   For instance, let's say you have a `Person` interface and two subclasses: `Employee` and `Customer`. If you configure your cache manager as follows:
  -```
  +```java
   CacheManagerBuilder.newCacheManagerBuilder().withSerializer(Employee.class, EmployeeSerializer.class).withSerializer(Person.class, PersonSerializer.class)
   ```
   then configuring a `Cache<Long, Employee>` would make it use the `EmployeeSerializer` while a `Cache<Long, Customer>` would make it use the `PersonSerializer`.
   
  -Each cache for which Ehcache instantiated a serializer (i.e.: the serializer was configured by its class name) will have its own instance.
  +Each cache for which Ehcache instantiates a serializer, it was configured by class name, will have its own `Serializer` instance.
  +
  +NOTE: Given the above, it is recommended to limit `Serializer` registration to concrete classes and not aim for generality.
   
   ==== Bundled implementations
   
  -By default, cache managers are pre-configured with specially optimized serializers that can handle the following types, in the following order:
  +By default, cache managers are pre-configured with specially optimized `Serializer` that can handle the following types, in the following order:
   
   - `java.io.Serializable`
   - `java.lang.Long`
  
positive.code: `com.pany.MyInterface` would need to deserialize a `com.pany.MyClassImplementingMyInterface` when the serialized object was of class `com.pany.MyClassImplementingMyInterface`
  and at the same time return an object of type `com.pany.AnotherClassImplementingMyInterface` when the serialized object was of class `com.pany.AnotherClassImplementingMyInterface`.
  
  Implement the following class:
  
  [source,java,indent=0]
  ----
  include::{sourcedir}/api/src/main/java/org/ehcache/spi/serialization/Serializer.java[]
  ----
  
  As the javadoc states, if you are planning to configure your serializer implementation at the cache manager level and use it with a persistent
  cache, you have to add a constructor that takes `ClassLoader classLoader, FileBasedPersistenceContext persistenceContext` as arguments while
  if you plan to use it for a transient cache, you have to add a constructor that takes `ClassLoader classLoader` as its sole argument.
  
  You can optionally implement `java.io.Closeable`. If you do, Ehcache will call `close()` when a cache using such serializer gets disposed of, but *only if*
  Ehcache instantiated the serializer itself.
  
  === Copiers
  
  As the on-heap store is capable of storing plain java objects as such,
  it is not necessary to use a costly serialization and deserialization mechanism to copy keys and values when a
  on-heap store is configured to store by value. For instance, some form of "copy constructor" mechanism is a lot
  more performant but requires custom code to be able to copy objects.
  
  Copiers are specific to the on-heap store: no other store makes use of copiers.
  
  By default, the on-heap mappings are stored by reference. The way to store them by value is to configure some copier(s)
  on it, either key, value or both.
  
  ==== How is a copier configured?
  
  There are two places where copiers can be configured:
  
  - at the cache level where one can use `CacheConfigurationBuilder.withKeyCopier()` and `CacheConfigurationBuilder.withValueCopier()`.
  Both instances and class names can be configured.
  - at the cache manager level where one can use `CacheManagerBuilder.withCopier(Class clazz, Class copier)`
  
  If a copier is configured directly at the cache level, it will be used, ignoring any cache manager level configuration and that cache will work in store-by-value mode.
  
  If a copier is configured at the cache manager level, upon initialization, a cache with no specifically configured copier will
  search through its cache manager's registered list of copiers and try to find one that directly matches the cache's key or value type. If such
  search fails, all the registered copiers will be tried in the added order to find one that handles compatible types.
  
  For instance, let's say you have a `Person` interface and two subclasses: `Employee` and `Customer`. If you configure your cache manager as follows:
  ```
  CacheManagerBuilder.newCacheManagerBuilder().withCopier(Employee.class, EmployeeCopier.class).withCopier(Person.class, PersonCopier.class)
  ```
  then configuring a `Cache<Long, Employee>` would make it use the `EmployeeCopier` while a `Cache<Long, Customer>` would make it use the `PersonCopier`.
  
  Each cache for which Ehcache instantiated a copier (i.e.: the copier was configured by its class name) will have its own instance.
  
  ==== Bundled implementations
  
  A `SerializingCopier` class exists in case you want to configure store-by-value on-heap using the configured (or default) serializer.
  
  ==== Lifecycle: instances vs class names
  
  When a copier class is configured (either at the cache or cache manager level), since Ehcache is responsible for creating the
  instance, it also is responsible for disposing of it. If a copier class name is configured and that class implements `java.io.Closeable` then
  `close()` will be called when the cache gets disposed of.
  
  ==== Writing your own Copier
  
  Implement the following class:
  
  [source,java,indent=0]
  ----
  include::{sourcedir}/api/src/main/java/org/ehcache/spi/copy/Copier.java[]
  ----
  
  `T copyForRead(T obj)` is invoked when a copy must be made upon a read operation (like a cache `get()`).
  `T copyForWrite(T obj)` is invoked when a copy must be made upon a write operation (like a cache `put()`).
  The separation between copying for read and for write can be useful when you want to store a lighter version of your objects into the cache.
  
  Alternatively, you can extend from `org.ehcache.impl.copy.ReadWriteCopier` if copying for read and copying for write implementations
  are identical and only have to implement `public abstract T copy(T obj)`.
  
negative.code: - `java.lang.String`
  - `byte[]`
  
  All bundled `Serializer` implementations support both persistent and transient caches.
  
  ==== Lifecycle: instances vs. class names
  
  When a `Serializer` is configured by providing an _instance_, it is up to the provider of that instance to manage its lifecycle.
  It will have dispose of any resource the serializer might hold upon and/or persisting and reloading the serializer's state.
  
  When a `Serializer` is configured by providing a _class name_ either at the cache or cache manager level, since Ehcache is responsible for creating the
  instance, it also is responsible for disposing of it.
  If the `Serializer` implements `java.io.Closeable` then `close()` will be called when the cache is closed and the `Serializer` no longer needed.
  
  ==== Writing your own serializer
  
  `Serializer` defines a very strict contract.
  So if you're planning to write your own implementation you have to keep in mind that the class of the serialized object MUST be retained after deserialization, that is:
  
  ```java
  object.getClass().equals( mySerializer.read(mySerializer.serialize(object)).getClass() )
  ```
  
  