Second cache level POC

Hi guys. :)


@guilhermeblanco / @instaclick have asked me to take a look into second level cache.
and i end up with the following solution..

There is lot of work todo before merge it, but i'd like to get your thoughts before i go any further on this approach.
I hope my drafts are good enough to explain the idea :

### Cache strategies

	* READ_ONLY 			 : ReadOnly cache can do reads, inserts and deletes, cannot perform updates or employ any locks.
	* NONSTRICT_READ_WRITE   : Nonstrict Read Write Cache doesn’t employ any locks but can do reads, inserts , updates and deletes.
	* READ_WRITE 			 : Read Write cache employs locks the entity before update/delete.


### classes / interfaces

* **Region** : 
    Defines a contract for accessing a entity/collection data cache. (Doesn’t employ any locks)


* **TransactionalRegion** :
	Defines a contract for accessing a entity/collection data cache. (Locks the data before update/delete.)


* **RegionAccess** : 
	Defines a contract to access a cache region


* **TransactionalRegionAccess** :
	Defines contract to access regions which hold transactionally-managed data.


* **CacheKey / EntityCacheKey / CollectionCacheKey/ QueryCacheKey**:
	Defines entity / collection key to be stored in the cache region.


* **EntityEntryStructure / CollectionEntryStructure**
	Build cache entries and rebuild entities/colection from cache


* **AccessProvider**
	Build RegionAccess based on entity / collection cache configuration



### OPERATIONS


#### INSERT :

	*********************************************************************************************
	UnitOfWork#commit
		Connection#beginTransaction
		Persister#executeInserts
		Connection#commit
		Persister#afterTransactionComplete
			-> EntityRegionAccessStrategy#afterInsert
    *********************************************************************************************
    METHOD      | READ-ONLY             | NONSTRICT-READ-WRITE      | READ-WRITE                |
    ---------------------------------------------------------------------------------------------
    afterInsert | add item to the cache | add item to the cache     | add item to the cache     |
    ---------------------------------------------------------------------------------------------


#### UPDATE :

	*********************************************************************************************
	UnitOfWork#commit
		Connection#beginTransaction
		Persister#update
			-> TransactionalRegionAccess#lockItem
			-> execute
		Connection#commit
		Persister#afterTransactionComplete
			-> RegionAccess#afterUpdate
			-> TransactionalRegionAccess#unlockItem
    *********************************************************************************************
    METHOD      | READ-ONLY             | NONSTRICT-READ-WRITE      | READ-WRITE                |
    ---------------------------------------------------------------------------------------------
    lockItem    | 			            | 			            	| lock item                 |
    ---------------------------------------------------------------------------------------------
    afterUpdate | throws exception      | update item cache         | update item cache         |
    ---------------------------------------------------------------------------------------------
    unlockItem  | 			            | 			            	| unlock item               |
    ---------------------------------------------------------------------------------------------


#### DELETE : 

	*********************************************************************************************
	UnitOfWork#commit
		Connection#beginTransaction
		Persister#delete
			-> TransactionalRegionAccess#lockItem
			-> execute
		Connection#commit
		Persister#afterTransactionComplete
			-> RegionAccess#evict
    *********************************************************************************************
    METHOD      | READ-ONLY             | NONSTRICT-READ-WRITE      | READ-WRITE                |
    ---------------------------------------------------------------------------------------------
    lockItem    |        				|                           | lock item                 |
    ---------------------------------------------------------------------------------------------
    evict 		| remove item cache     | remove item cache     	| remove item cache         |
    ---------------------------------------------------------------------------------------------


#### USAGE : 
```php
<?php

/**
 * @Entity
 * @Table("cache_state")
 * @Cache("NONSTRICT_READ_WRITE")
 */
class State
{
    /**
     * @Id
     * @GeneratedValue
     * @Column(type="integer")
     */
    protected $id;
    /**
     * @Column
     */
    protected $name;
    /**
     * @Cache()
     * @ManyToOne(targetEntity="Country")
     * @JoinColumn(name="country_id", referencedColumnName="id")
     */
    protected $country;
    /**
     * @Cache()
     * @OneToMany(targetEntity="City", mappedBy="state")
     */
    protected $cities;
}
```

```php
<?php

$em->persist(new State($name, $country));
$em->flush();							     // Put itens into cache

$em->clear();								 // Clear entity manager

$state 	 = $em->find('Entity\State', 1);	 // Retreive item from cache
$country = $state->getCountry();			 // Retreive item from cache
$cities  = $state->getCities();				 // Load from database and put into cache

$state->setName("New Name");
$em->persist($state);
$em->flush();							     // Update item cache

$em->clear();								 // Clear entity manager

$em->find('Entity\State', 1)->getCities();   // Retreive from cache

$metadata 	= $em->getClassMetadata('Entity\State');
$identifier	= array('id'=>$state->getId());

$em->getCache()->containsEntity($metadata, $identifier)	// Check if the cache exists
$em->getCache()->evictEntity($metadata, $identifier);	// Remove an entity from cache
$em->getCache()->evictEntityRegion($metadata);			// Remove all entities from cache

$em->getCache()->containsCollection($metadata, 'cities', $identifier); 	// Check if the cache exists        
$em->getCache()->evictCollection($metadata, 'cities', $identifier); 	// Remove an entity collection from cache
$em->getCache()->evictCollectionRegion($metadata, 'cities');			// Remove all collections from cache

```

#### TODO :
* handle many to many collection
* handle inheritance
* remove/add colection items on update
* improve region tests
* improve access strategy tests
* implement xml / yml /php drivers
* implement transaction region
* implement transaction  access strategy
* .... ????