[jbosscache-commits] JBoss Cache SVN: r6554 - in pojo/tags: 2.2.0.CR7 and 5 other directories.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Tue Aug 12 00:16:03 EDT 2008


Author: jason.greene at jboss.com
Date: 2008-08-12 00:16:02 -0400 (Tue, 12 Aug 2008)
New Revision: 6554

Added:
   pojo/tags/2.2.0.CR7/
   pojo/tags/2.2.0.CR7/pom.xml
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/PojoCache.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/Reference.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/AbstractHandler.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/AdvisedPojoHandler.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/ArrayHandler.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/CollectionClassHandler.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/InternalHelper.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/MethodDeclarations.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/NotificationDispatcher.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/ObjectGraphHandler.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/PojoCacheDelegate.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/PojoCacheImpl.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/PojoInstance.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/PojoUtil.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/ReferenceImpl.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/SerializableObjectHandler.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/jmx/PojoCacheJmxWrapper.java
   pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/FindReferencesTest.java
   pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ListTest.java
   pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/Listener.java
   pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/MapTest.java
   pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ObjectTest.java
   pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ReplicatedListTest.java
   pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ReplicatedMapTest.java
   pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ReplicatedObjectTest.java
   pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ReplicatedSetTest.java
   pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/SetTest.java
Removed:
   pojo/tags/2.2.0.CR7/pom.xml
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/PojoCache.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/AbstractHandler.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/AdvisedPojoHandler.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/ArrayHandler.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/CollectionClassHandler.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/InternalHelper.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/MethodDeclarations.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/NotificationDispatcher.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/ObjectGraphHandler.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/PojoCacheDelegate.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/PojoCacheImpl.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/PojoInstance.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/PojoUtil.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/Referrer.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/SerializableObjectHandler.java
   pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/jmx/PojoCacheJmxWrapper.java
   pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ListTest.java
   pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/Listener.java
   pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/MapTest.java
   pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ObjectTest.java
   pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ReplicatedListTest.java
   pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ReplicatedMapTest.java
   pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ReplicatedObjectTest.java
   pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ReplicatedSetTest.java
   pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/SetTest.java
Log:
Tag CR7


Copied: pojo/tags/2.2.0.CR7 (from rev 6310, pojo/trunk)

Deleted: pojo/tags/2.2.0.CR7/pom.xml
===================================================================
--- pojo/trunk/pom.xml	2008-07-16 17:30:08 UTC (rev 6310)
+++ pojo/tags/2.2.0.CR7/pom.xml	2008-08-12 04:16:02 UTC (rev 6554)
@@ -1,299 +0,0 @@
-<?xml version="1.0"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <properties>
-    <jbosscache-pojo-version>2.2.0-SNAPSHOT</jbosscache-pojo-version>
-    <jbosscache-core-version>2.2.0.CR5</jbosscache-core-version>
-    <jboss.aop.version>2.0.0.CR14</jboss.aop.version>
-  </properties>
-  <parent>
-    <groupId>org.jboss.cache</groupId>
-    <artifactId>jbosscache-common-parent</artifactId>
-    <version>1.1</version>
-  </parent>
-  <groupId>org.jboss.cache</groupId>
-  <artifactId>jbosscache-pojo</artifactId>
-  <version>${jbosscache-pojo-version}</version>
-  <name>JBoss Cache - POJO Edition</name>
-  <description>JBoss Cache - POJO Edition</description>
-  <packaging>jar</packaging>
-  <dependencies>
-    <dependency>
-      <groupId>org.jboss.aop</groupId>
-      <artifactId>jboss-aop</artifactId>
-      <version>${jboss.aop.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.jboss.cache</groupId>
-      <artifactId>jbosscache-core</artifactId>
-      <version>${jbosscache-core-version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.jboss.cache</groupId>
-      <artifactId>jbosscache-core</artifactId>
-      <version>${jbosscache-core-version}</version>
-      <type>test-jar</type>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>commons-logging</groupId>
-      <artifactId>commons-logging</artifactId>
-      <version>1.0.4</version>
-    </dependency>
-    <dependency>
-       <groupId>net.jcip</groupId>
-       <artifactId>jcip-annotations</artifactId>
-       <version>1.0</version>
-       <optional>true</optional>
-    </dependency>
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-javadoc-plugin</artifactId>
-        <executions>
-          <execution>
-            <phase>package</phase>
-            <goals>
-              <goal>javadoc</goal>
-            </goals>
-            <configuration>
-              <aggregate>${jbosscache.reports.aggregate}</aggregate>
-              <links>
-                <link>http://java.sun.com/j2se/1.5.0/docs/api/</link>
-                <link>http://java.sun.com/javaee/5/docs/api/</link>
-                <link>http://labs.jboss.org/file-access/default/members/jbosscache/freezone/docs/2.1.0.GA/apidocs/</link>
-              </links>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-    <plugin>
-        <artifactId>maven-assembly-plugin</artifactId>
-        <version>2.2-beta-1</version>
-        <executions>
-          <execution>
-            <id>assemble</id>
-            <phase>install</phase>
-            <goals>
-              <goal>attached</goal>
-            </goals>
-            <configuration>
-              <descriptors>
-                <descriptor>assembly/bin.xml</descriptor>
-                <descriptor>assembly/doc.xml</descriptor>
-                <descriptor>assembly/all.xml</descriptor>
-              </descriptors>
-              <finalName>${artifactId}-${jbosscache-pojo-version}</finalName>
-              <outputDirectory>target/distribution</outputDirectory>
-              <workDirectory>target/assembly/work</workDirectory>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <version>2.3</version>
-        <configuration>
-          <systemProperties>
-            <property>
-              <name>bind.address</name>
-              <value>127.0.0.1</value>
-            </property>
-            <property>
-              <name>java.net.preferIPv4Stack</name>
-              <value>true</value>
-            </property>
-            <property>
-              <name>jgroups.stack</name>
-              <value>udp</value>
-            </property>
-          </systemProperties>
-          <groups>functional</groups>
-          <forkMode>always</forkMode>
-          <argLine>-Djboss.aop.path=${basedir}/src/main/resources/META-INF/pojocache-aop.xml -javaagent:${settings.localRepository}/org/jboss/aop/jboss-aop/${jboss.aop.version}/jboss-aop-${jboss.aop.version}.jar</argLine>
-          <!-- Warning, this does not work right on 2.4-SNAPSHOT, (see SUREFIRE-349) -->
-          <!-- This seems to fail in some cases on 2.3 as well, disable for now -->
-          <useSystemClassLoader>true</useSystemClassLoader>
-          <redirectTestOutputToFile>false</redirectTestOutputToFile>
-        </configuration>
-      </plugin>
-      <!-- the docbook generation plugin for the user guide -->
-      <plugin>
-        <groupId>org.jboss.maven.plugins</groupId>
-        <artifactId>maven-jdocbook-plugin</artifactId>
-        <version>2.0.0</version>
-        <extensions>true</extensions>
-        <dependencies>
-            <dependency>
-               <groupId>org.jboss</groupId>
-               <artifactId>jbossorg-docbook-xslt</artifactId>
-               <version>1.0.0</version>
-            </dependency>
-            <dependency>
-               <groupId>org.jboss</groupId>
-               <artifactId>jbossorg-jdocbook-style</artifactId>
-               <version>1.0.0</version>
-               <type>jdocbook-style</type>
-            </dependency>
-           <dependency>
-                  <groupId>com.uwyn</groupId>
-                  <artifactId>jhighlight</artifactId>
-                  <version>1.0</version>
-              </dependency>
-              <dependency>
-                  <groupId>de.java2html</groupId>
-                  <artifactId>java2html</artifactId>
-                  <version>5.0</version>
-              </dependency>
-              <dependency>
-                  <groupId>org.richfaces.docs</groupId>
-                  <artifactId>highlight</artifactId>
-                  <version>3.1.4.GA</version>
-              </dependency>
-         </dependencies>
-        <executions>
-
-          <!-- The User Guide-->
-          <execution>
-            <id>userguide_en</id>
-            <phase>package</phase>
-            <goals>
-              <goal>resources</goal>
-              <goal>generate</goal>
-            </goals>
-            <configuration>
-              <sourceDocumentName>master.xml</sourceDocumentName>
-              <sourceDirectory>${basedir}/src/main/docbook/userguide/en</sourceDirectory>
-              <imageResource>
-                <directory>${basedir}/src/main/docbook/images</directory>
-              </imageResource>
-              <cssResource>
-                <directory>${basedir}/src/main/docbook/css</directory>
-              </cssResource>
-              <targetDirectory>${basedir}/target/docbook/userguide_en</targetDirectory>
-              <formats>
-                <format>
-                  <formatName>pdf</formatName>
-				  <stylesheetResource>classpath:/xslt/org/jboss/main-pdf.xsl</stylesheetResource>
-                  <finalName>userguide_en.pdf</finalName>
-                </format>
-				<format>
-                	<formatName>html</formatName>
-				    <stylesheetResource>classpath:/xslt/org/jboss/main-html.xsl</stylesheetResource>
-				    <finalName>index.html</finalName>
-				</format>
-				<format>
-					<formatName>html_single</formatName>
-				    <stylesheetResource>classpath:/xslt/org/jboss/nochunk-html.xsl</stylesheetResource>
-				    <finalName>index.html</finalName>
-				</format>
-			  </formats>
-              <options>
-                <xincludeSupported>false</xincludeSupported>
-              </options>
-            </configuration>
-          </execution>
-
-          <!-- The Tutorial -->
-          <execution>
-            <id>tutorial_en</id>
-            <phase>package</phase>
-            <goals>
-              <goal>resources</goal>
-              <goal>generate</goal>
-            </goals>
-            <configuration>
-              <sourceDocumentName>master.xml</sourceDocumentName>
-              <sourceDirectory>${basedir}/src/main/docbook/tutorial/en</sourceDirectory>
-              <imageResource>
-                <directory>${basedir}/src/main/docbook/images</directory>
-              </imageResource>
-              <cssResource>
-                <directory>${basedir}/src/main/docbook/css</directory>
-              </cssResource>
-              <targetDirectory>${basedir}/target/docbook/tutorial_en</targetDirectory>
-              <formats>
-                <format>
-                  <formatName>pdf</formatName>
-				  <stylesheetResource>classpath:/xslt/org/jboss/main-pdf.xsl</stylesheetResource>
-                  <finalName>tutorial_en.pdf</finalName>
-                </format>
-				<format>
-                	<formatName>html</formatName>
-				    <stylesheetResource>classpath:/xslt/org/jboss/main-html.xsl</stylesheetResource>
-				    <finalName>index.html</finalName>
-				</format>
-				<format>
-					<formatName>html_single</formatName>
-				    <stylesheetResource>classpath:/xslt/org/jboss/nochunk-html.xsl</stylesheetResource>
-				    <finalName>index.html</finalName>
-				</format>
-              </formats>
-              <options>
-                <xincludeSupported>false</xincludeSupported>
-              </options>
-            </configuration>
-          </execution>
-
-          <!-- the FAQs -->
-          <execution>
-            <id>faq_en</id>
-            <phase>package</phase>
-            <goals>
-              <goal>resources</goal>
-              <goal>generate</goal>
-            </goals>
-            <configuration>
-              <sourceDocumentName>master.xml</sourceDocumentName>
-              <sourceDirectory>${basedir}/src/main/docbook/faq/en</sourceDirectory>
-              <imageResource>
-                <directory>${basedir}/src/main/docbook/images</directory>
-              </imageResource>
-              <cssResource>
-                <directory>${basedir}/src/main/docbook/css</directory>
-              </cssResource>
-              <targetDirectory>${basedir}/target/docbook/faq_en</targetDirectory>
-              <formats>
-                <format>
-                  <formatName>pdf</formatName>
-				  <stylesheetResource>classpath:/xslt/org/jboss/main-pdf.xsl</stylesheetResource>
-                  <finalName>faq_en.pdf</finalName>
-                </format>
-				<format>
-                	<formatName>html</formatName>
-				    <stylesheetResource>classpath:/xslt/org/jboss/main-html.xsl</stylesheetResource>
-				    <finalName>index.html</finalName>
-				</format>
-				<format>
-					<formatName>html_single</formatName>
-				    <stylesheetResource>classpath:/xslt/org/jboss/nochunk-html.xsl</stylesheetResource>
-				    <finalName>index.html</finalName>
-				</format>
-              </formats>
-              <options>
-                <xincludeSupported>false</xincludeSupported>
-              </options>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-
-  <!-- basic JBoss repository so that the common parent POM in jbosscache-support can be found -->
-  <repositories>
-    <repository>
-      <id>snapshots.jboss.org</id>
-      <url>http://snapshots.jboss.org/maven2</url>
-    </repository>
-    <repository>
-      <id>repository.jboss.org</id>
-      <url>http://repository.jboss.org/maven2</url>
-    </repository>
-  </repositories>
-</project>

Copied: pojo/tags/2.2.0.CR7/pom.xml (from rev 6323, pojo/trunk/pom.xml)
===================================================================
--- pojo/tags/2.2.0.CR7/pom.xml	                        (rev 0)
+++ pojo/tags/2.2.0.CR7/pom.xml	2008-08-12 04:16:02 UTC (rev 6554)
@@ -0,0 +1,299 @@
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <properties>
+    <jbosscache-pojo-version>2.2.0.CR7</jbosscache-pojo-version>
+    <jbosscache-core-version>2.2.0.CR7</jbosscache-core-version>
+    <jboss.aop.version>2.0.0.CR15</jboss.aop.version>
+  </properties>
+  <parent>
+    <groupId>org.jboss.cache</groupId>
+    <artifactId>jbosscache-common-parent</artifactId>
+    <version>1.1</version>
+  </parent>
+  <groupId>org.jboss.cache</groupId>
+  <artifactId>jbosscache-pojo</artifactId>
+  <version>${jbosscache-pojo-version}</version>
+  <name>JBoss Cache - POJO Edition</name>
+  <description>JBoss Cache - POJO Edition</description>
+  <packaging>jar</packaging>
+  <dependencies>
+    <dependency>
+      <groupId>org.jboss.aop</groupId>
+      <artifactId>jboss-aop</artifactId>
+      <version>${jboss.aop.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.jboss.cache</groupId>
+      <artifactId>jbosscache-core</artifactId>
+      <version>${jbosscache-core-version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.jboss.cache</groupId>
+      <artifactId>jbosscache-core</artifactId>
+      <version>${jbosscache-core-version}</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>commons-logging</groupId>
+      <artifactId>commons-logging</artifactId>
+      <version>1.0.4</version>
+    </dependency>
+    <dependency>
+       <groupId>net.jcip</groupId>
+       <artifactId>jcip-annotations</artifactId>
+       <version>1.0</version>
+       <optional>true</optional>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-javadoc-plugin</artifactId>
+        <executions>
+          <execution>
+            <phase>package</phase>
+            <goals>
+              <goal>javadoc</goal>
+            </goals>
+            <configuration>
+              <aggregate>${jbosscache.reports.aggregate}</aggregate>
+              <links>
+                <link>http://java.sun.com/j2se/1.5.0/docs/api/</link>
+                <link>http://java.sun.com/javaee/5/docs/api/</link>
+                <link>http://labs.jboss.org/file-access/default/members/jbosscache/freezone/docs/2.1.0.GA/apidocs/</link>
+              </links>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    <plugin>
+        <artifactId>maven-assembly-plugin</artifactId>
+        <version>2.2-beta-1</version>
+        <executions>
+          <execution>
+            <id>assemble</id>
+            <phase>install</phase>
+            <goals>
+              <goal>attached</goal>
+            </goals>
+            <configuration>
+              <descriptors>
+                <descriptor>assembly/bin.xml</descriptor>
+                <descriptor>assembly/doc.xml</descriptor>
+                <descriptor>assembly/all.xml</descriptor>
+              </descriptors>
+              <finalName>${artifactId}-${jbosscache-pojo-version}</finalName>
+              <outputDirectory>target/distribution</outputDirectory>
+              <workDirectory>target/assembly/work</workDirectory>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <version>2.3</version>
+        <configuration>
+          <systemProperties>
+            <property>
+              <name>bind.address</name>
+              <value>127.0.0.1</value>
+            </property>
+            <property>
+              <name>java.net.preferIPv4Stack</name>
+              <value>true</value>
+            </property>
+            <property>
+              <name>jgroups.stack</name>
+              <value>udp</value>
+            </property>
+          </systemProperties>
+          <groups>functional</groups>
+          <forkMode>always</forkMode>
+          <argLine>-Djboss.aop.path=${basedir}/src/main/resources/META-INF/pojocache-aop.xml -javaagent:${settings.localRepository}/org/jboss/aop/jboss-aop/${jboss.aop.version}/jboss-aop-${jboss.aop.version}.jar</argLine>
+          <!-- Warning, this does not work right on 2.4-SNAPSHOT, (see SUREFIRE-349) -->
+          <!-- This seems to fail in some cases on 2.3 as well, disable for now -->
+          <useSystemClassLoader>true</useSystemClassLoader>
+          <redirectTestOutputToFile>false</redirectTestOutputToFile>
+        </configuration>
+      </plugin>
+      <!-- the docbook generation plugin for the user guide -->
+      <plugin>
+        <groupId>org.jboss.maven.plugins</groupId>
+        <artifactId>maven-jdocbook-plugin</artifactId>
+        <version>2.0.0</version>
+        <extensions>true</extensions>
+        <dependencies>
+            <dependency>
+               <groupId>org.jboss</groupId>
+               <artifactId>jbossorg-docbook-xslt</artifactId>
+               <version>1.0.0</version>
+            </dependency>
+            <dependency>
+               <groupId>org.jboss</groupId>
+               <artifactId>jbossorg-jdocbook-style</artifactId>
+               <version>1.0.0</version>
+               <type>jdocbook-style</type>
+            </dependency>
+           <dependency>
+                  <groupId>com.uwyn</groupId>
+                  <artifactId>jhighlight</artifactId>
+                  <version>1.0</version>
+              </dependency>
+              <dependency>
+                  <groupId>de.java2html</groupId>
+                  <artifactId>java2html</artifactId>
+                  <version>5.0</version>
+              </dependency>
+              <dependency>
+                  <groupId>org.richfaces.docs</groupId>
+                  <artifactId>highlight</artifactId>
+                  <version>3.1.4.GA</version>
+              </dependency>
+         </dependencies>
+        <executions>
+
+          <!-- The User Guide-->
+          <execution>
+            <id>userguide_en</id>
+            <phase>package</phase>
+            <goals>
+              <goal>resources</goal>
+              <goal>generate</goal>
+            </goals>
+            <configuration>
+              <sourceDocumentName>master.xml</sourceDocumentName>
+              <sourceDirectory>${basedir}/src/main/docbook/userguide/en</sourceDirectory>
+              <imageResource>
+                <directory>${basedir}/src/main/docbook/images</directory>
+              </imageResource>
+              <cssResource>
+                <directory>${basedir}/src/main/docbook/css</directory>
+              </cssResource>
+              <targetDirectory>${basedir}/target/docbook/userguide_en</targetDirectory>
+              <formats>
+                <format>
+                  <formatName>pdf</formatName>
+				  <stylesheetResource>classpath:/xslt/org/jboss/main-pdf.xsl</stylesheetResource>
+                  <finalName>userguide_en.pdf</finalName>
+                </format>
+				<format>
+                	<formatName>html</formatName>
+				    <stylesheetResource>classpath:/xslt/org/jboss/main-html.xsl</stylesheetResource>
+				    <finalName>index.html</finalName>
+				</format>
+				<format>
+					<formatName>html_single</formatName>
+				    <stylesheetResource>classpath:/xslt/org/jboss/nochunk-html.xsl</stylesheetResource>
+				    <finalName>index.html</finalName>
+				</format>
+			  </formats>
+              <options>
+                <xincludeSupported>false</xincludeSupported>
+              </options>
+            </configuration>
+          </execution>
+
+          <!-- The Tutorial -->
+          <execution>
+            <id>tutorial_en</id>
+            <phase>package</phase>
+            <goals>
+              <goal>resources</goal>
+              <goal>generate</goal>
+            </goals>
+            <configuration>
+              <sourceDocumentName>master.xml</sourceDocumentName>
+              <sourceDirectory>${basedir}/src/main/docbook/tutorial/en</sourceDirectory>
+              <imageResource>
+                <directory>${basedir}/src/main/docbook/images</directory>
+              </imageResource>
+              <cssResource>
+                <directory>${basedir}/src/main/docbook/css</directory>
+              </cssResource>
+              <targetDirectory>${basedir}/target/docbook/tutorial_en</targetDirectory>
+              <formats>
+                <format>
+                  <formatName>pdf</formatName>
+				  <stylesheetResource>classpath:/xslt/org/jboss/main-pdf.xsl</stylesheetResource>
+                  <finalName>tutorial_en.pdf</finalName>
+                </format>
+				<format>
+                	<formatName>html</formatName>
+				    <stylesheetResource>classpath:/xslt/org/jboss/main-html.xsl</stylesheetResource>
+				    <finalName>index.html</finalName>
+				</format>
+				<format>
+					<formatName>html_single</formatName>
+				    <stylesheetResource>classpath:/xslt/org/jboss/nochunk-html.xsl</stylesheetResource>
+				    <finalName>index.html</finalName>
+				</format>
+              </formats>
+              <options>
+                <xincludeSupported>false</xincludeSupported>
+              </options>
+            </configuration>
+          </execution>
+
+          <!-- the FAQs -->
+          <execution>
+            <id>faq_en</id>
+            <phase>package</phase>
+            <goals>
+              <goal>resources</goal>
+              <goal>generate</goal>
+            </goals>
+            <configuration>
+              <sourceDocumentName>master.xml</sourceDocumentName>
+              <sourceDirectory>${basedir}/src/main/docbook/faq/en</sourceDirectory>
+              <imageResource>
+                <directory>${basedir}/src/main/docbook/images</directory>
+              </imageResource>
+              <cssResource>
+                <directory>${basedir}/src/main/docbook/css</directory>
+              </cssResource>
+              <targetDirectory>${basedir}/target/docbook/faq_en</targetDirectory>
+              <formats>
+                <format>
+                  <formatName>pdf</formatName>
+				  <stylesheetResource>classpath:/xslt/org/jboss/main-pdf.xsl</stylesheetResource>
+                  <finalName>faq_en.pdf</finalName>
+                </format>
+				<format>
+                	<formatName>html</formatName>
+				    <stylesheetResource>classpath:/xslt/org/jboss/main-html.xsl</stylesheetResource>
+				    <finalName>index.html</finalName>
+				</format>
+				<format>
+					<formatName>html_single</formatName>
+				    <stylesheetResource>classpath:/xslt/org/jboss/nochunk-html.xsl</stylesheetResource>
+				    <finalName>index.html</finalName>
+				</format>
+              </formats>
+              <options>
+                <xincludeSupported>false</xincludeSupported>
+              </options>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+  <!-- basic JBoss repository so that the common parent POM in jbosscache-support can be found -->
+  <repositories>
+    <repository>
+      <id>snapshots.jboss.org</id>
+      <url>http://snapshots.jboss.org/maven2</url>
+    </repository>
+    <repository>
+      <id>repository.jboss.org</id>
+      <url>http://repository.jboss.org/maven2</url>
+    </repository>
+  </repositories>
+</project>

Deleted: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/PojoCache.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/PojoCache.java	2008-07-16 17:30:08 UTC (rev 6310)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/PojoCache.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -1,260 +0,0 @@
-/*
- * JBoss, the OpenSource J2EE webOS
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package org.jboss.cache.pojo;
-
-import java.util.Collection;
-import java.util.Map;
-import java.util.regex.Pattern;
-
-import org.jboss.cache.Cache;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.pojo.annotation.Replicable;
-import org.jboss.cache.pojo.notification.annotation.PojoCacheListener;
-
-/**
- * <p>Main PojoCache APIs. PojoCache is an in-memory, transactional, fine-grained, and
- * object-oriented POJO (plain old Java object) distributed cache system. It
- * differs from the traditional generic distributed cache library by operating on the
- * POJO level directly without requiring that object to be serializable. It can preserve
- * object graph relationship during replication or persistency. It also track the
- * replication via fine-grained maner, i.e., only modified fields are replicated.</p>
- *
- * @author Ben Wang
- * @author Jason T. Greene
- * @since 2.0
- */
-public interface PojoCache
-{
-   /**
-    * <p>Attach a POJO into PojoCache. It will also recursively put any
-    * sub-POJO into the cache system. A POJO can be the following and have the
-    * consqeuences when attached:</p> <p/> <li>it is Replicable, that is, it
-    * has been annotated with {@link Replicable} annotation (or via XML),
-    * and has
-    * been "instrumented" either compile- or load-time. The POJO will be mapped
-    * recursively to the system and fine-grained replication will be
-    * performed.</li> <li>It is Serializable. The POJO will still be stored in
-    * the cache system. However, it is treated as an "opaque" object per se.
-    * That is, the POJO will neither be intercepted
-    * (for fine-grained operation) or object relantionship will be
-    * maintained.</li>
-    * <li>Neither of above. In this case, a user can specify whether it wants
-    * this POJO to be stored (e.g., replicated or persistent). If not, a
-    * PojoCacheException will be thrown.</li>
-    *
-    * @param id   An id String to identify the object in the cache. To promote
-    *             concurrency, we recommend the use of hierarchical String separating by a
-    *             designated separator. Default is "/" but it can be set differently via a
-    *             System property, jbosscache.separator in the future release. E.g., "/ben",
-    *             or "/student/joe", etc.
-    * @param pojo object to be inerted into the cache. If null, it will nullify
-    *             the fqn node.
-    * @return Existing POJO or null if there is none.
-    * @throws PojoCacheException Throws if there is an error related to the cache operation.
-    */
-   Object attach(String id, Object pojo) throws PojoCacheException;
-
-   /**
-    * <p>Attach a POJO into PojoCache. It will also recursively put any
-    * sub-POJO into the cache system. A POJO can be the following and have the
-    * consequences when attached:</p> <p/> <li>it is Replicable, that is, it
-    * has been annotated with {@link Replicable} annotation (or via XML),
-    * and has
-    * been "instrumented" either compile- or load-time. The POJO will be mapped
-    * recursively to the system and fine-grained replication will be
-    * performed.</li> <li>It is Serializable. The POJO will still be stored in
-    * the cache system. However, it is treated as an "opaque" object per se.
-    * That is, the POJO will neither be intercepted
-    * (for fine-grained operation) or object relationship will be
-    * maintained.</li>
-    * <li>Neither of above. In this case, a user can specify whether it wants
-    * this POJO to be stored (e.g., replicated or persistent). If not, a
-    * PojoCacheException will be thrown.</li>
-    *
-    * @since 2.1
-    * @param id   the Fqn that specifies the location in the cache to attach the object
-    * @param pojo object to be inserted into the cache. If null, it will nullify
-    *             the fqn node.
-    * @return Existing POJO or null if there is none.
-    * @throws PojoCacheException Throws if there is an error related to the cache operation.
-    */
-   Object attach(Fqn<?> id, Object pojo) throws PojoCacheException;
-
-   /**
-    * Remove POJO object from the cache.
-    *
-    * @param id Is string that associates with this node.
-    * @return Original value object from this node.
-    * @throws PojoCacheException Throws if there is an error related to the cache operation.
-    */
-   Object detach(String id) throws PojoCacheException;
-
-   /**
-    * Remove POJO object from the cache.
-    *
-    * @since 2.1
-    * @param id location of the object to remove
-    * @return Original value object from this node.
-    * @throws PojoCacheException Throws if there is an error related to the cache operation.
-    */
-   Object detach(Fqn<?> id) throws PojoCacheException;
-
-   /**
-    * Return the POJO id that is associated with PojoCache. Note that if a POJO has not yet
-    * attached to the cache system, it will simply return null.
-    *
-    * @param pojo The POJO that is attached to PojoCache.
-    * @return String ID. Null if not existed.
-    */
-   String getPojoID(Object pojo);
-
-   /**
-    * Determines if an object is attached at a particular location. This is somewhat less expensive
-    * than find() because an object is not created, and internal reference links are not traversed.
-    *
-    * @since 2.1
-    * @param id the location in the cache to examine
-    * @return true if an attached object exists, false if not
-    */
-   boolean exists(Fqn<?> id);
-
-   /**
-    * Retrieve POJO from the cache system. Return null if object does not exist in the cache.
-    * Note that this operation is fast if there is already a POJO instance attached to the cache.
-    *
-    * @param id that associates with this node.
-    * @return Current content value. Null if does not exist.
-    * @throws PojoCacheException Throws if there is an error related to the cache operation.
-    */
-   Object find(String id) throws PojoCacheException;
-
-   /**
-    * Retrieve POJO from the cache system. Return null if object does not exist in the cache.
-    * Note that this operation is fast if there is already a POJO instance attached to the cache.
-    *
-    * @since 2.1
-    * @param id that associates with this node.
-    * @return Current content value. Null if does not exist.
-    * @throws PojoCacheException Throws if there is an error related to the cache operation.
-    */
-   Object find(Fqn<?> id) throws PojoCacheException;
-
-   /**
-    * Query all managed POJO objects under the id recursively. Note that this will not return
-    * the sub-object POJOs, e.g., if <em>Person</em> has a sub-object of <em>Address</em>, it
-    * won't return <em>Address</em> pojo. Also note also that this operation is not thread-safe
-    * now. In addition, it assumes that once a POJO is found with a id, no more POJO is stored
-    * under the children of the id. That is, we don't mix the id with different POJOs.
-    *
-    * @param id The starting place to find all POJOs.
-    * @return Map of all POJOs found with (id, POJO) pair. Return size of 0, if not found.
-    * @throws PojoCacheException Throws if there is an error related to the cache operation.
-    */
-   Map<Fqn<?>, Object> findAll(String id) throws PojoCacheException;
-
-   /**
-    * Query all managed POJO objects under the id recursively. Note that this will not return
-    * the sub-object POJOs, e.g., if <em>Person</em> has a sub-object of <em>Address</em>, it
-    * won't return <em>Address</em> pojo. Also note also that this operation is not thread-safe
-    * now. In addition, it assumes that once a POJO is found with a id, no more POJO is stored
-    * under the children of the id. That is, we don't mix the id with different POJOs.
-    *
-    * @since 2.1
-    * @param id The starting place to find all POJOs.
-    * @return Map of all POJOs found with (id, POJO) pair. Return size of 0, if not found.
-    * @throws PojoCacheException Throws if there is an error related to the cache operation.
-    */
-   Map<Fqn<?>, Object> findAll(Fqn<?> id) throws PojoCacheException;
-
-   /**
-    * Lifecycle method to start PojoCache.
-    *
-    * @throws PojoCacheException
-    */
-   void create() throws PojoCacheException;
-
-   /**
-    * Lifecycle method to start PojoCache.
-    *
-    * @throws PojoCacheException
-    */
-   void start() throws PojoCacheException;
-
-   /**
-    * Lifecycle method to stop PojoCache. Note that PojoCache can be stopped and started
-    * repeatedly.
-    *
-    * @throws PojoCacheException
-    */
-   void stop() throws PojoCacheException;
-
-   /**
-    * Lifecycle method to destroy PojoCache.
-    *
-    * @throws PojoCacheException
-    */
-   void destroy() throws PojoCacheException;
-
-   /**
-    * <p>
-    * Add a PojoCache listener. A given listener instance can only be added once.
-    * To have a duplicate listener simply create a new instance.
-    *
-    * <p>
-    * The listener must be annotated with the {@link PojoCacheListener} annotation, and
-    * all callback methods need to be annotated with the respective event annotations.
-    * Otherwise, an exception will be thrown.
-    *
-    * @param listener the listener instance to register
-    * @throws IllegalArgumentException if listener does not conform to annotation requirements
-    * @see PojoCacheListener for examples
-    */
-   void addListener(Object listener);
-
-   /**
-    * <p>
-    * Add a PojoCache listener that will only monitor a specific ID(FQN) pattern.
-    * A given listener instance can only be added once, whether or not there is
-    * a pattern. To have a duplicate listener simply create a new instance.
-    *
-    * <p>
-    * The listener must be annotated with the {@link PojoCacheListener} annotation, and
-    * all callback methods need to be annotated with the respective event annotations.
-    * Otherwise, an exception will be thrown.
-    *
-    * @param listener the listener instance to register
-    * @param pattern the ID pattern for notifications of interest
-    * @throws IllegalArgumentException if listener does not conform to annotation requirements
-    * @see PojoCacheListener for examples
-    */
-   void addListener(Object listener, Pattern pattern);
-
-   /**
-    * Retrieve a read-only list of listeners.
-    */
-   Collection<Object> getListeners();
-
-   /**
-    * Remove the specific listener.
-    *
-    * @param listener the listener to remove
-    */
-   void removeListener(Object listener);
-   
-   /**
-    * Get's the thread context for all POJO Cache operations.
-    * 
-    * @return the current thread's context
-    * @since 2.1
-    */
-   PojoCacheThreadContext getThreadContext();
-
-   /**
-    * Obtain the underlying generic cache system. Use this for non-POJO cache operation, e.g.
-    */
-   Cache<Object, Object> getCache();
-}

Copied: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/PojoCache.java (from rev 6374, pojo/trunk/src/main/java/org/jboss/cache/pojo/PojoCache.java)
===================================================================
--- pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/PojoCache.java	                        (rev 0)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/PojoCache.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -0,0 +1,287 @@
+/*
+ * JBoss, the OpenSource J2EE webOS
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jboss.cache.pojo;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import org.jboss.cache.Cache;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.pojo.annotation.Replicable;
+import org.jboss.cache.pojo.notification.annotation.PojoCacheListener;
+
+/**
+ * <p>Main PojoCache APIs. PojoCache is an in-memory, transactional, fine-grained, and
+ * object-oriented POJO (plain old Java object) distributed cache system. It
+ * differs from the traditional generic distributed cache library by operating on the
+ * POJO level directly without requiring that object to be serializable. It can preserve
+ * object graph relationship during replication or persistency. It also track the
+ * replication via fine-grained maner, i.e., only modified fields are replicated.</p>
+ *
+ * @author Ben Wang
+ * @author Jason T. Greene
+ * @since 2.0
+ */
+public interface PojoCache
+{
+   /**
+    * <p>Attach a POJO into PojoCache. It will also recursively put any
+    * sub-POJO into the cache system. A POJO can be the following and have the
+    * consqeuences when attached:</p> <p/> <li>it is Replicable, that is, it
+    * has been annotated with {@link Replicable} annotation (or via XML),
+    * and has
+    * been "instrumented" either compile- or load-time. The POJO will be mapped
+    * recursively to the system and fine-grained replication will be
+    * performed.</li> <li>It is Serializable. The POJO will still be stored in
+    * the cache system. However, it is treated as an "opaque" object per se.
+    * That is, the POJO will neither be intercepted
+    * (for fine-grained operation) or object relantionship will be
+    * maintained.</li>
+    * <li>Neither of above. In this case, a user can specify whether it wants
+    * this POJO to be stored (e.g., replicated or persistent). If not, a
+    * PojoCacheException will be thrown.</li>
+    *
+    * @param id   An id String to identify the object in the cache. To promote
+    *             concurrency, we recommend the use of hierarchical String separating by a
+    *             designated separator. Default is "/" but it can be set differently via a
+    *             System property, jbosscache.separator in the future release. E.g., "/ben",
+    *             or "/student/joe", etc.
+    * @param pojo object to be inerted into the cache. If null, it will nullify
+    *             the fqn node.
+    * @return Existing POJO or null if there is none.
+    * @throws PojoCacheException Throws if there is an error related to the cache operation.
+    */
+   Object attach(String id, Object pojo) throws PojoCacheException;
+
+   /**
+    * <p>Attach a POJO into PojoCache. It will also recursively put any
+    * sub-POJO into the cache system. A POJO can be the following and have the
+    * consequences when attached:</p> <p/> <li>it is Replicable, that is, it
+    * has been annotated with {@link Replicable} annotation (or via XML),
+    * and has
+    * been "instrumented" either compile- or load-time. The POJO will be mapped
+    * recursively to the system and fine-grained replication will be
+    * performed.</li> <li>It is Serializable. The POJO will still be stored in
+    * the cache system. However, it is treated as an "opaque" object per se.
+    * That is, the POJO will neither be intercepted
+    * (for fine-grained operation) or object relationship will be
+    * maintained.</li>
+    * <li>Neither of above. In this case, a user can specify whether it wants
+    * this POJO to be stored (e.g., replicated or persistent). If not, a
+    * PojoCacheException will be thrown.</li>
+    *
+    * @since 2.1
+    * @param id   the Fqn that specifies the location in the cache to attach the object
+    * @param pojo object to be inserted into the cache. If null, it will nullify
+    *             the fqn node.
+    * @return Existing POJO or null if there is none.
+    * @throws PojoCacheException Throws if there is an error related to the cache operation.
+    */
+   Object attach(Fqn<?> id, Object pojo) throws PojoCacheException;
+
+   /**
+    * Remove POJO object from the cache.
+    *
+    * @param id Is string that associates with this node.
+    * @return Original value object from this node.
+    * @throws PojoCacheException Throws if there is an error related to the cache operation.
+    */
+   Object detach(String id) throws PojoCacheException;
+
+   /**
+    * Remove POJO object from the cache.
+    *
+    * @since 2.1
+    * @param id location of the object to remove
+    * @return Original value object from this node.
+    * @throws PojoCacheException Throws if there is an error related to the cache operation.
+    */
+   Object detach(Fqn<?> id) throws PojoCacheException;
+
+  /**
+   * Return the <code>Fqn</code> of the internal node containing the data of this attached object.
+   * <p>
+   * Note that if the object is not attached to the cache system, this method will simply return
+   * null. Same for any object of an immediate type (primitive wrapper types, String, or Class) or
+   * of any <code>Serializable</code> types.
+   * </p>
+   *
+   * @param object Any object.
+   * @return <code>Fqn</code> of the internal data node. <code>null</code> if the object is
+   *         immediate, serializable, or not in the cache.
+   */
+  Fqn<?> getInternalFqn(Object object);
+
+  /**
+   * Return a list of the references from attached objects to this object. For each reference it
+   * returns a {@link Reference} object containing the <code>Fqn</code> of the referrer object and
+   * the name of the field that contains the reference.
+   * <p>
+   * If the node is not attached to the cache, this method will return an empty list. Same for any
+   * object of an immediate type (primitive wrapper types, String, or Class) or of any
+   * <code>Serializable</code> types.
+   * </p>
+   * <p>
+   * For external references (i.e. when the object was directly attached to the cache by user code)
+   * the <code>Reference.fieldName</code> property is <code>null</code>. Otherwise it is the name
+   * of the field that contains the reference to this object.
+   * </p>
+   *
+   * @param object Any object.
+   * @return Collection of internal references to the given object. Empty collection if the object is
+   *         immediate, serializable, or not in the cache.
+   */
+   Collection<Reference> getReferences(Object object);
+
+   /**
+    * Determines if an object is attached at a particular location. This is somewhat less expensive
+    * than find() because an object is not created, and internal reference links are not traversed.
+    *
+    * @since 2.1
+    * @param id the location in the cache to examine
+    * @return true if an attached object exists, false if not
+    */
+   boolean exists(Fqn<?> id);
+
+   /**
+    * Retrieve POJO from the cache system. Return null if object does not exist in the cache.
+    * Note that this operation is fast if there is already a POJO instance attached to the cache.
+    *
+    * @param id that associates with this node.
+    * @return Current content value. Null if does not exist.
+    * @throws PojoCacheException Throws if there is an error related to the cache operation.
+    */
+   Object find(String id) throws PojoCacheException;
+
+   /**
+    * Retrieve POJO from the cache system. Return null if object does not exist in the cache.
+    * Note that this operation is fast if there is already a POJO instance attached to the cache.
+    *
+    * @since 2.1
+    * @param id that associates with this node.
+    * @return Current content value. Null if does not exist.
+    * @throws PojoCacheException Throws if there is an error related to the cache operation.
+    */
+   Object find(Fqn<?> id) throws PojoCacheException;
+
+   /**
+    * Query all managed POJO objects under the id recursively. Note that this will not return
+    * the sub-object POJOs, e.g., if <em>Person</em> has a sub-object of <em>Address</em>, it
+    * won't return <em>Address</em> pojo. Also note also that this operation is not thread-safe
+    * now. In addition, it assumes that once a POJO is found with a id, no more POJO is stored
+    * under the children of the id. That is, we don't mix the id with different POJOs.
+    *
+    * @param id The starting place to find all POJOs.
+    * @return Map of all POJOs found with (id, POJO) pair. Return size of 0, if not found.
+    * @throws PojoCacheException Throws if there is an error related to the cache operation.
+    */
+   Map<Fqn<?>, Object> findAll(String id) throws PojoCacheException;
+
+   /**
+    * Query all managed POJO objects under the id recursively. Note that this will not return
+    * the sub-object POJOs, e.g., if <em>Person</em> has a sub-object of <em>Address</em>, it
+    * won't return <em>Address</em> pojo. Also note also that this operation is not thread-safe
+    * now. In addition, it assumes that once a POJO is found with a id, no more POJO is stored
+    * under the children of the id. That is, we don't mix the id with different POJOs.
+    *
+    * @since 2.1
+    * @param id The starting place to find all POJOs.
+    * @return Map of all POJOs found with (id, POJO) pair. Return size of 0, if not found.
+    * @throws PojoCacheException Throws if there is an error related to the cache operation.
+    */
+   Map<Fqn<?>, Object> findAll(Fqn<?> id) throws PojoCacheException;
+
+   /**
+    * Lifecycle method to start PojoCache.
+    *
+    * @throws PojoCacheException
+    */
+   void create() throws PojoCacheException;
+
+   /**
+    * Lifecycle method to start PojoCache.
+    *
+    * @throws PojoCacheException
+    */
+   void start() throws PojoCacheException;
+
+   /**
+    * Lifecycle method to stop PojoCache. Note that PojoCache can be stopped and started
+    * repeatedly.
+    *
+    * @throws PojoCacheException
+    */
+   void stop() throws PojoCacheException;
+
+   /**
+    * Lifecycle method to destroy PojoCache.
+    *
+    * @throws PojoCacheException
+    */
+   void destroy() throws PojoCacheException;
+
+   /**
+    * <p>
+    * Add a PojoCache listener. A given listener instance can only be added once.
+    * To have a duplicate listener simply create a new instance.
+    *
+    * <p>
+    * The listener must be annotated with the {@link PojoCacheListener} annotation, and
+    * all callback methods need to be annotated with the respective event annotations.
+    * Otherwise, an exception will be thrown.
+    *
+    * @param listener the listener instance to register
+    * @throws IllegalArgumentException if listener does not conform to annotation requirements
+    * @see PojoCacheListener for examples
+    */
+   void addListener(Object listener);
+
+   /**
+    * <p>
+    * Add a PojoCache listener that will only monitor a specific ID(FQN) pattern.
+    * A given listener instance can only be added once, whether or not there is
+    * a pattern. To have a duplicate listener simply create a new instance.
+    *
+    * <p>
+    * The listener must be annotated with the {@link PojoCacheListener} annotation, and
+    * all callback methods need to be annotated with the respective event annotations.
+    * Otherwise, an exception will be thrown.
+    *
+    * @param listener the listener instance to register
+    * @param pattern the ID pattern for notifications of interest
+    * @throws IllegalArgumentException if listener does not conform to annotation requirements
+    * @see PojoCacheListener for examples
+    */
+   void addListener(Object listener, Pattern pattern);
+
+   /**
+    * Retrieve a read-only list of listeners.
+    */
+   Collection<Object> getListeners();
+
+   /**
+    * Remove the specific listener.
+    *
+    * @param listener the listener to remove
+    */
+   void removeListener(Object listener);
+   
+   /**
+    * Get's the thread context for all POJO Cache operations.
+    * 
+    * @return the current thread's context
+    * @since 2.1
+    */
+   PojoCacheThreadContext getThreadContext();
+
+   /**
+    * Obtain the underlying generic cache system. Use this for non-POJO cache operation, e.g.
+    */
+   Cache<Object, Object> getCache();
+}

Copied: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/Reference.java (from rev 6374, pojo/trunk/src/main/java/org/jboss/cache/pojo/Reference.java)
===================================================================
--- pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/Reference.java	                        (rev 0)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/Reference.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -0,0 +1,50 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.cache.pojo;
+
+import org.jboss.cache.Fqn;
+
+/**
+ * A reference to an attached object. This class represents both normal Fqn aliases, and
+ * references from other attached objects.
+ *
+ * @author Dan Berindei <dan.berindei at gmail.com>
+ */
+public interface Reference
+{
+   /**
+    * Returns the Fqn of the referring node. Cannot be <code>null</code>.
+    *
+    * @return <code>Fqn</code> of the referring node.
+    */
+   public Fqn<?> getFqn();
+
+   /**
+    * Returns the name of the node key which references the attached object, or null
+    * if the Fqn is a normal alias to the internal node. If there is a key, then this is
+    * typically a field name or collection index.
+    *
+    * @return Name of the field or key/index in the collection that is containing the reference.
+    */
+   public String getKey();
+}
\ No newline at end of file

Deleted: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/AbstractHandler.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/AbstractHandler.java	2008-07-16 17:30:08 UTC (rev 6310)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/AbstractHandler.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -1,43 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.cache.pojo.impl;
-
-import org.jboss.cache.Fqn;
-
-abstract class AbstractHandler
-{
-
-   public AbstractHandler()
-   {
-      super();
-   }
-   
-   protected abstract boolean handles(Class<?> clazz);
-
-   protected abstract Object remove(Fqn<?> fqn, Fqn<?> referenceingFqn, Object result);
-
-   protected abstract void put(Fqn<?> fqn, Fqn<?> referencingFqn, Object obj);
-
-   protected abstract Object get(Fqn<?> fqn, Class<?> clazz, PojoInstance pojoInstance);
-
-   protected abstract Fqn<?> getFqn(Object obj);
-}
\ No newline at end of file

Copied: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/AbstractHandler.java (from rev 6374, pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/AbstractHandler.java)
===================================================================
--- pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/AbstractHandler.java	                        (rev 0)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/AbstractHandler.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -0,0 +1,44 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.cache.pojo.impl;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.pojo.Reference;
+
+abstract class AbstractHandler
+{
+
+   public AbstractHandler()
+   {
+      super();
+   }
+
+   protected abstract boolean handles(Class<?> clazz);
+
+   protected abstract Object remove(Fqn<?> fqn, Reference reference, Object result);
+
+   protected abstract void put(Fqn<?> fqn, Reference reference, Object obj);
+
+   protected abstract Object get(Fqn<?> fqn, Class<?> clazz, PojoInstance pojoInstance);
+
+   protected abstract Fqn<?> getFqn(Object obj);
+}

Deleted: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/AdvisedPojoHandler.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/AdvisedPojoHandler.java	2008-07-16 17:30:08 UTC (rev 6310)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/AdvisedPojoHandler.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -1,257 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.cache.pojo.impl;
-
-import java.lang.reflect.Field;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.jboss.aop.Advised;
-import org.jboss.aop.ClassInstanceAdvisor;
-import org.jboss.aop.InstanceAdvisor;
-import org.jboss.cache.Cache;
-import org.jboss.cache.CacheException;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.pojo.PojoCacheException;
-import org.jboss.cache.pojo.interceptors.dynamic.BaseInterceptor;
-import org.jboss.cache.pojo.interceptors.dynamic.CacheFieldInterceptor;
-import org.jboss.cache.pojo.memory.FieldPersistentReference;
-import org.jboss.cache.pojo.util.AopUtil;
-import org.jboss.cache.pojo.util.Instantiator;
-import org.jboss.cache.pojo.util.ObjectUtil;
-
-/**
- * Handling the advised pojo operations. No consideration of object graph here.
- *
- * @author Ben Wang
- *         Date: Aug 4, 2005
- * @version $Id$
- */
-class AdvisedPojoHandler extends AbstractHandler
-{
-   private final Log log = LogFactory.getLog(AdvisedPojoHandler.class);
-   private Cache<Object, Object> cache_;
-   private PojoCacheImpl pCache_;
-   private PojoUtil util_;
-
-   public AdvisedPojoHandler(PojoCacheImpl pCache, InternalHelper internal,
-                             PojoUtil util)
-   {
-      pCache_ = pCache;
-      cache_ = pCache_.getCache();
-      util_ = util;
-   }
-
-   @Override
-   protected Fqn<?> getFqn(Object obj)
-   {
-      if (obj instanceof Advised)
-      {
-         InstanceAdvisor advisor = ((Advised) obj)._getInstanceAdvisor();
-         if (advisor == null)
-            throw new PojoCacheException("_putObject(): InstanceAdvisor is null for: " + obj);
-
-         // Step Check for cross references
-         BaseInterceptor interceptor = AopUtil.findCacheInterceptor(advisor);
-         if (interceptor != null)
-            return interceptor.getFqn();
-      }
-
-      return null;
-   }
-
-   @Override
-   protected Object get(Fqn<?> fqn, Class<?> clazz, PojoInstance pojoInstance) throws CacheException
-   {
-      CachedType type = pCache_.getCachedType(clazz);
-      Object obj = Instantiator.newInstance(clazz);
-
-      // Eager initialize final fields, since these may not be intercepted
-
-      try
-      {
-         for (FieldPersistentReference ref : type.getFinalFields())
-         {
-            Field field = ref.getField();
-            Object result;
-
-            if (CachedType.isSimpleAttribute(field))
-               result = cache_.get(fqn, field.getName());
-            else
-               result = pCache_.find(fqn, field.getName(), obj);
-
-            field.set(obj, result);
-         }
-      }
-      catch (Exception e)
-      {
-         log.warn("Could not initialize final fields on object: " + ObjectUtil.identityString(obj));
-      }
-
-      InstanceAdvisor advisor = ((Advised) obj)._getInstanceAdvisor();
-      CacheFieldInterceptor interceptor = new CacheFieldInterceptor(pCache_, fqn, type);
-      interceptor.setAopInstance(pojoInstance);
-      util_.attachInterceptor(obj, advisor, interceptor);
-      return obj;
-   }
-
-   @Override
-   protected void put(Fqn<?> fqn, Fqn<?> referencingFqn, Object obj) throws CacheException
-   {
-      CachedType type = pCache_.getCachedType(obj.getClass());
-      // We have a clean slate then.
-      InstanceAdvisor advisor = ((Advised) obj)._getInstanceAdvisor();
-      // TODO workaround for deserialiased objects
-      if (advisor == null)
-      {
-         advisor = new ClassInstanceAdvisor(obj);
-         ((Advised) obj)._setInstanceAdvisor(advisor);
-      }
-
-      // Let's do batch update via Map instead
-      Map map = new HashMap();
-      // Always initialize the ref count so we can mark this as an AopNode.
-      PojoInstance pojoInstance = InternalHelper.initializeAopInstance(referencingFqn);
-      map.put(PojoInstance.KEY, pojoInstance);
-      pojoInstance.setPojoClass(type.getType());
-      // we will do it recursively.
-      // Map of sub-objects that are non-primitive
-      Map subPojoMap = new HashMap();
-
-      for (Iterator i = type.getFields().iterator(); i.hasNext();)
-      {
-         Field field = (Field) (((FieldPersistentReference) i.next())).get();
-         Object value = null;
-         try
-         {
-            value = field.get(obj);
-         }
-         catch (IllegalAccessException e)
-         {
-            throw new CacheException("field access failed", e);
-         }
-
-         // we simply treat field that has @Serializable as a primitive type.
-         if (CachedType.isSimpleAttribute(field))
-         {
-            // switched using batch update
-            map.put(field.getName(), value);
-         }
-         else
-         {
-            subPojoMap.put(field, value);
-         }
-      }
-
-      // Use option to skip locking since we have parent lock already.
-//      cache_.getInvocationContext().getOptionOverrides().setSuppressLocking(true);
-
-      cache_.getRoot().addChild(fqn).putAll(map);
-
-      // Insert interceptor after PojoInstance has been written to the cache
-      // This prevents JBCACHE-1078 with pessimistic locking, optimistic is still a problem
-      CacheFieldInterceptor interceptor = new CacheFieldInterceptor(pCache_, fqn, type);
-      interceptor.setAopInstance(pojoInstance);
-      util_.attachInterceptor(obj, advisor, interceptor);
-
-//      cache_.getInvocationContext().getOptionOverrides().setSuppressLocking(false);
-      // This is in-memory operation only
-      InternalHelper.setPojo(pojoInstance, obj);
-
-      for (Object o : subPojoMap.keySet())
-      {
-         Field field = (Field) o;
-         Object value = subPojoMap.get(field);
-         if (value == null) continue; // really no need to map the POJO.
-         pCache_.attach(fqn, value, field.getName(), obj);
-         // If it is Collection classes, we replace it with dynamic proxy.
-         // But we will have to ignore it if value is null
-         if (value instanceof Map || value instanceof List || value instanceof Set)
-         {
-            Object newValue = pCache_.find(fqn, field.getName(), obj);
-            util_.inMemorySubstitution(obj, field, newValue);
-         }
-      }
-
-      // Need to make sure this is behind put such that obj.toString is done correctly.
-      if (log.isDebugEnabled())
-      {
-         log.debug("internalPut(): inserting with fqn: " + fqn);
-      }
-   }
-
-   @Override
-   protected Object remove(Fqn<?> fqn, Fqn<?> referencingFqn, Object result) throws CacheException
-   {
-      CachedType type = pCache_.getCachedType(result.getClass());
-      InstanceAdvisor advisor = ((Advised) result)._getInstanceAdvisor();
-      for (Iterator i = type.getFields().iterator(); i.hasNext();)
-      {
-         Field field = (Field) (((FieldPersistentReference) i.next())).get();
-         Object value = null;
-
-         if (! CachedType.isSimpleAttribute(field))
-         {
-            value = pCache_.detach(fqn, field.getName(), result);
-
-            // Check for Collection. If it is, we need to reset the original reference.
-            if ((value instanceof Map || value instanceof List || value instanceof Set))
-            {
-               // If this Collection class, we are returning the original value already
-               util_.inMemorySubstitution(result, field, value);
-            }
-         }
-         else
-         {
-            // Update last known field state
-            value = cache_.get(fqn,  field.getName());
-            util_.inMemorySubstitution(result, field, value);
-         }
-      }
-
-      cache_.removeNode(fqn);
-      // Determine if we want to keep the interceptor for later use.
-      CacheFieldInterceptor interceptor = (CacheFieldInterceptor) AopUtil.findCacheInterceptor(advisor);
-      // Remember to remove the interceptor from in-memory object but make sure it belongs to me first.
-      if (interceptor != null)
-      {
-         if (log.isDebugEnabled())
-         {
-            log.debug("regularRemoveObject(): removed cache interceptor fqn: " + fqn + " interceptor: " + interceptor);
-         }
-         util_.detachInterceptor(advisor, interceptor);
-      }
-
-      return result;
-   }
-
-   @Override
-   protected boolean handles(Class<?> clazz)
-   {
-      return Advised.class.isAssignableFrom(clazz);
-   }
-}

Copied: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/AdvisedPojoHandler.java (from rev 6374, pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/AdvisedPojoHandler.java)
===================================================================
--- pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/AdvisedPojoHandler.java	                        (rev 0)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/AdvisedPojoHandler.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -0,0 +1,254 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.cache.pojo.impl;
+
+import java.lang.reflect.Field;
+import java.util.*;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.aop.Advised;
+import org.jboss.aop.ClassInstanceAdvisor;
+import org.jboss.aop.InstanceAdvisor;
+import org.jboss.cache.Cache;
+import org.jboss.cache.CacheException;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.pojo.PojoCacheException;
+import org.jboss.cache.pojo.Reference;
+import org.jboss.cache.pojo.interceptors.dynamic.BaseInterceptor;
+import org.jboss.cache.pojo.interceptors.dynamic.CacheFieldInterceptor;
+import org.jboss.cache.pojo.memory.FieldPersistentReference;
+import org.jboss.cache.pojo.util.AopUtil;
+import org.jboss.cache.pojo.util.Instantiator;
+import org.jboss.cache.pojo.util.ObjectUtil;
+
+/**
+ * Handling the advised pojo operations. No consideration of object graph here.
+ *
+ * @author Ben Wang
+ *         Date: Aug 4, 2005
+ * @version $Id$
+ */
+class AdvisedPojoHandler extends AbstractHandler
+{
+   private final Log log = LogFactory.getLog(AdvisedPojoHandler.class);
+   private Cache<Object, Object> cache_;
+   private PojoCacheImpl pCache_;
+   private PojoUtil util_;
+
+   public AdvisedPojoHandler(PojoCacheImpl pCache, InternalHelper internal,
+                             PojoUtil util)
+   {
+      pCache_ = pCache;
+      cache_ = pCache_.getCache();
+      util_ = util;
+   }
+
+   @Override
+   protected Fqn<?> getFqn(Object obj)
+   {
+      if (obj instanceof Advised)
+      {
+         InstanceAdvisor advisor = ((Advised) obj)._getInstanceAdvisor();
+         if (advisor == null)
+            throw new PojoCacheException("_putObject(): InstanceAdvisor is null for: " + obj);
+
+         // Step Check for cross references
+         BaseInterceptor interceptor = AopUtil.findCacheInterceptor(advisor);
+         if (interceptor != null)
+            return interceptor.getFqn();
+      }
+
+      return null;
+   }
+
+   @Override
+   protected Object get(Fqn<?> fqn, Class<?> clazz, PojoInstance pojoInstance) throws CacheException
+   {
+      CachedType type = pCache_.getCachedType(clazz);
+      Object obj = Instantiator.newInstance(clazz);
+
+      // Eager initialize final fields, since these may not be intercepted
+
+      try
+      {
+         for (FieldPersistentReference ref : type.getFinalFields())
+         {
+            Field field = ref.getField();
+            Object result;
+
+            if (CachedType.isSimpleAttribute(field))
+               result = cache_.get(fqn, field.getName());
+            else
+               result = pCache_.find(fqn, field.getName(), obj);
+
+            field.set(obj, result);
+         }
+      }
+      catch (Exception e)
+      {
+         log.warn("Could not initialize final fields on object: " + ObjectUtil.identityString(obj));
+      }
+
+      InstanceAdvisor advisor = ((Advised) obj)._getInstanceAdvisor();
+      CacheFieldInterceptor interceptor = new CacheFieldInterceptor(pCache_, fqn, type);
+      interceptor.setAopInstance(pojoInstance);
+      util_.attachInterceptor(obj, advisor, interceptor);
+      return obj;
+   }
+
+   @Override
+   protected void put(Fqn<?> fqn, Reference reference, Object obj) throws CacheException
+   {
+      CachedType type = pCache_.getCachedType(obj.getClass());
+      // We have a clean slate then.
+      InstanceAdvisor advisor = ((Advised) obj)._getInstanceAdvisor();
+      // TODO workaround for deserialiased objects
+      if (advisor == null)
+      {
+         advisor = new ClassInstanceAdvisor(obj);
+         ((Advised) obj)._setInstanceAdvisor(advisor);
+      }
+
+      // Let's do batch update via Map instead
+      Map map = new HashMap();
+      // Always initialize the ref count so we can mark this as an AopNode.
+      PojoInstance pojoInstance = InternalHelper.initializeAopInstance(reference);
+      map.put(PojoInstance.KEY, pojoInstance);
+      pojoInstance.setPojoClass(type.getType());
+      // we will do it recursively.
+      // Map of sub-objects that are non-primitive
+      Map subPojoMap = new HashMap();
+
+      for (Iterator i = type.getFields().iterator(); i.hasNext();)
+      {
+         Field field = (Field) (((FieldPersistentReference) i.next())).get();
+         Object value = null;
+         try
+         {
+            value = field.get(obj);
+         }
+         catch (IllegalAccessException e)
+         {
+            throw new CacheException("field access failed", e);
+         }
+
+         // we simply treat field that has @Serializable as a primitive type.
+         if (CachedType.isSimpleAttribute(field))
+         {
+            // switched using batch update
+            map.put(field.getName(), value);
+         }
+         else
+         {
+            subPojoMap.put(field, value);
+         }
+      }
+
+      // Use option to skip locking since we have parent lock already.
+//      cache_.getInvocationContext().getOptionOverrides().setSuppressLocking(true);
+
+      cache_.getRoot().addChild(fqn).putAll(map);
+
+      // Insert interceptor after PojoInstance has been written to the cache
+      // This prevents JBCACHE-1078 with pessimistic locking, optimistic is still a problem
+      CacheFieldInterceptor interceptor = new CacheFieldInterceptor(pCache_, fqn, type);
+      interceptor.setAopInstance(pojoInstance);
+      util_.attachInterceptor(obj, advisor, interceptor);
+
+//      cache_.getInvocationContext().getOptionOverrides().setSuppressLocking(false);
+      // This is in-memory operation only
+      InternalHelper.setPojo(pojoInstance, obj);
+
+      for (Object o : subPojoMap.keySet())
+      {
+         Field field = (Field) o;
+         Object value = subPojoMap.get(field);
+         if (value == null) continue; // really no need to map the POJO.
+         pCache_.attach(fqn, value, field.getName(), obj);
+         // If it is Collection classes, we replace it with dynamic proxy.
+         // But we will have to ignore it if value is null
+         if (value instanceof Map || value instanceof List || value instanceof Set)
+         {
+            Object newValue = pCache_.find(fqn, field.getName(), obj);
+            util_.inMemorySubstitution(obj, field, newValue);
+         }
+      }
+
+      // Need to make sure this is behind put such that obj.toString is done correctly.
+      if (log.isDebugEnabled())
+      {
+         log.debug("internalPut(): inserting with fqn: " + fqn);
+      }
+   }
+
+   @Override
+   protected Object remove(Fqn<?> fqn, Reference referencingFqn, Object result) throws CacheException
+   {
+      CachedType type = pCache_.getCachedType(result.getClass());
+      InstanceAdvisor advisor = ((Advised) result)._getInstanceAdvisor();
+      for (Iterator i = type.getFields().iterator(); i.hasNext();)
+      {
+         Field field = (Field) (((FieldPersistentReference) i.next())).get();
+         Object value = null;
+
+         if (! CachedType.isSimpleAttribute(field))
+         {
+            value = pCache_.detach(fqn, field.getName(), result);
+
+            // Check for Collection. If it is, we need to reset the original reference.
+            if ((value instanceof Map || value instanceof List || value instanceof Set))
+            {
+               // If this Collection class, we are returning the original value already
+               util_.inMemorySubstitution(result, field, value);
+            }
+         }
+         else
+         {
+            // Update last known field state
+            value = cache_.get(fqn,  field.getName());
+            util_.inMemorySubstitution(result, field, value);
+         }
+      }
+
+      cache_.removeNode(fqn);
+      // Determine if we want to keep the interceptor for later use.
+      CacheFieldInterceptor interceptor = (CacheFieldInterceptor) AopUtil.findCacheInterceptor(advisor);
+      // Remember to remove the interceptor from in-memory object but make sure it belongs to me first.
+      if (interceptor != null)
+      {
+         if (log.isDebugEnabled())
+         {
+            log.debug("regularRemoveObject(): removed cache interceptor fqn: " + fqn + " interceptor: " + interceptor);
+         }
+         util_.detachInterceptor(advisor, interceptor);
+      }
+
+      return result;
+   }
+
+   @Override
+   protected boolean handles(Class<?> clazz)
+   {
+      return Advised.class.isAssignableFrom(clazz);
+   }
+}

Deleted: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/ArrayHandler.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/ArrayHandler.java	2008-07-16 17:30:08 UTC (rev 6310)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/ArrayHandler.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -1,90 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.cache.pojo.impl;
-
-import org.jboss.cache.Fqn;
-import org.jboss.cache.pojo.collection.CachedArray;
-import org.jboss.cache.pojo.collection.CachedArrayRegistry;
-
-/**
- * Handles array types.
- *
- * @author Jason T. Greene
- */
-public class ArrayHandler extends AbstractHandler
-{
-   private final PojoCacheImpl cache;
-   private final PojoUtil util = new PojoUtil();
-
-   ArrayHandler(PojoCacheImpl cache)
-   {
-      this.cache = cache;
-   }
-
-   protected Fqn<?> getFqn(Object array)
-   {
-      CachedArray cached = CachedArrayRegistry.lookup(array);
-      return cached != null ? cached.getFqn() : null;
-   }
-
-
-   protected void put(Fqn<?> fqn, Fqn<?> referencingFqn, Object obj)
-   {
-      // Always initialize the ref count so that we can mark this as an AopNode.
-      PojoInstance pojoInstance = InternalHelper.initializeAopInstance(referencingFqn);
-      pojoInstance.set(obj);
-      pojoInstance.setPojoClass(obj.getClass());
-      cache.getCache().put(fqn, PojoInstance.KEY, pojoInstance);
-
-      CachedArray cached = CachedArray.create(fqn, cache, obj);
-      util.attachArray(obj, cached);
-   }
-
-   @Override
-   protected Object get(Fqn<?> fqn, Class<?> clazz, PojoInstance pojo)
-   {
-      CachedArray cached = CachedArray.load(fqn, cache, clazz);
-      Object array = cached.toArray();
-      CachedArrayRegistry.register(array, cached);
-
-      return array;
-   }
-
-   @Override
-   protected Object remove(Fqn<?> fqn, Fqn<?> referencingFqn, Object obj)
-   {
-      CachedArray cached = CachedArrayRegistry.lookup(obj);
-      if (cached != null) {
-         util.detachArray(obj, cached);
-         cached.destroy();
-      }
-
-      return obj;
-   }
-
-   @Override
-   protected boolean handles(Class<?> clazz)
-   {
-      return clazz.isArray();
-   }
-
-}

Copied: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/ArrayHandler.java (from rev 6374, pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/ArrayHandler.java)
===================================================================
--- pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/ArrayHandler.java	                        (rev 0)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/ArrayHandler.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -0,0 +1,91 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.cache.pojo.impl;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.pojo.Reference;
+import org.jboss.cache.pojo.collection.CachedArray;
+import org.jboss.cache.pojo.collection.CachedArrayRegistry;
+
+/**
+ * Handles array types.
+ *
+ * @author Jason T. Greene
+ */
+public class ArrayHandler extends AbstractHandler
+{
+   private final PojoCacheImpl cache;
+   private final PojoUtil util = new PojoUtil();
+
+   ArrayHandler(PojoCacheImpl cache)
+   {
+      this.cache = cache;
+   }
+
+   protected Fqn<?> getFqn(Object array)
+   {
+      CachedArray cached = CachedArrayRegistry.lookup(array);
+      return cached != null ? cached.getFqn() : null;
+   }
+
+   @Override
+   protected void put(Fqn<?> fqn, Reference reference, Object obj)
+   {
+      // Always initialize the ref count so that we can mark this as an AopNode.
+      PojoInstance pojoInstance = InternalHelper.initializeAopInstance(reference);
+      pojoInstance.set(obj);
+      pojoInstance.setPojoClass(obj.getClass());
+      cache.getCache().put(fqn, PojoInstance.KEY, pojoInstance);
+
+      CachedArray cached = CachedArray.create(fqn, cache, obj);
+      util.attachArray(obj, cached);
+   }
+
+   @Override
+   protected Object get(Fqn<?> fqn, Class<?> clazz, PojoInstance pojo)
+   {
+      CachedArray cached = CachedArray.load(fqn, cache, clazz);
+      Object array = cached.toArray();
+      CachedArrayRegistry.register(array, cached);
+
+      return array;
+   }
+
+   @Override
+   protected Object remove(Fqn<?> fqn, Reference referencingFqn, Object obj)
+   {
+      CachedArray cached = CachedArrayRegistry.lookup(obj);
+      if (cached != null) {
+         util.detachArray(obj, cached);
+         cached.destroy();
+      }
+
+      return obj;
+   }
+
+   @Override
+   protected boolean handles(Class<?> clazz)
+   {
+      return clazz.isArray();
+   }
+
+}

Deleted: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/CollectionClassHandler.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/CollectionClassHandler.java	2008-07-16 17:30:08 UTC (rev 6310)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/CollectionClassHandler.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -1,293 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-
-package org.jboss.cache.pojo.impl;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.jboss.aop.proxy.ClassProxy;
-import org.jboss.cache.Cache;
-import org.jboss.cache.CacheException;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.pojo.PojoCacheException;
-import org.jboss.cache.pojo.collection.CollectionInterceptorUtil;
-import org.jboss.cache.pojo.interceptors.dynamic.AbstractCollectionInterceptor;
-import org.jboss.cache.pojo.interceptors.dynamic.BaseInterceptor;
-
-/**
- * Handling the Collection class management. Has no consideration of object graph here.
- *
- * @author Ben Wang
- *         Date: Aug 4, 2005
- * @version $Id$
- */
-class CollectionClassHandler extends AbstractHandler
-{
-   private final Log log = LogFactory.getLog(CollectionClassHandler.class);
-   private Cache<Object, Object> cache_;
-   private PojoCacheImpl pCache_;
-   private InternalHelper internal_;
-
-   public CollectionClassHandler(PojoCacheImpl pCache, InternalHelper internal)
-   {
-      pCache_ = pCache;
-      cache_ = pCache_.getCache();
-      internal_ = internal;
-   }
-
-   protected Fqn<?> getFqn(Object collection)
-   {
-      if (! (collection instanceof ClassProxy))
-         return null;
-
-      BaseInterceptor interceptor = CollectionInterceptorUtil.getInterceptor((ClassProxy) collection);
-      return interceptor != null ? interceptor.getFqn() : null;
-   }
-
-   protected Object get(Fqn fqn, Class clazz, PojoInstance pojoInstance)
-         throws CacheException
-   {
-      Object obj = null;
-      try
-      {
-         if (Map.class.isAssignableFrom(clazz))
-         {
-            Object map = clazz.newInstance();
-            obj = CollectionInterceptorUtil.createMapProxy(pCache_, fqn, clazz, (Map) map);
-         }
-         else if (List.class.isAssignableFrom(clazz))
-         {
-            Object list = clazz.newInstance();
-            obj = CollectionInterceptorUtil.createListProxy(pCache_, fqn, clazz, (List) list);
-         }
-         else if (Set.class.isAssignableFrom(clazz))
-         {
-            Object set = clazz.newInstance();
-            obj = CollectionInterceptorUtil.createSetProxy(pCache_, fqn, clazz, (Set) set);
-         }
-      }
-      catch (Exception e)
-      {
-         throw new CacheException("failure creating proxy", e);
-      }
-
-      return obj;
-   }
-
-   protected void put(Fqn fqn, Fqn referencingFqn, Object obj) throws CacheException
-   {
-      boolean isCollection = false;
-
-      CachedType type = null;
-      if (obj instanceof ClassProxy)
-      {
-         throw new IllegalStateException("CollectionClassHandler.put(): obj is an ClassProxy instance " + obj);
-      }
-
-      type = pCache_.getCachedType(obj.getClass());
-
-      //JBCACHE-760: for collection - put initialized aopInstance in fqn
-      if (!(obj instanceof Map || obj instanceof List || obj instanceof Set))
-      {
-         return;
-      }
-
-      // Always initialize the ref count so that we can mark this as an AopNode.
-      PojoInstance pojoInstance = InternalHelper.initializeAopInstance(referencingFqn);
-      pojoInstance.set(obj);
-      pojoInstance.setPojoClass(type.getType());
-      cache_.put(fqn, PojoInstance.KEY, pojoInstance);
-
-      if (obj instanceof Map)
-      {
-         if (log.isDebugEnabled())
-         {
-            log.debug("collectionPutObject(): aspectized obj is a Map type of size: " + ((Map) obj).size());
-         }
-
-         // Let's replace it with a proxy if necessary
-         Map map = (Map) obj;
-         if (!(obj instanceof ClassProxy))
-         {
-            Class clazz = obj.getClass();
-            try
-            {
-               obj = CollectionInterceptorUtil.createMapProxy(pCache_, fqn, clazz, (Map) obj);
-            }
-            catch (Exception e)
-            {
-               throw new CacheException("failure creating proxy", e);
-            }
-
-            checkMapRecursion(map, obj);
-         }
-
-         isCollection = true;
-         // populate via the proxied collection
-         for (Iterator i = map.entrySet().iterator(); i.hasNext();)
-         {
-            Map.Entry entry = (Map.Entry) i.next();
-            ((Map) obj).put(entry.getKey(), entry.getValue());
-         }
-
-      }
-      else if (obj instanceof List)
-      {
-         if (log.isDebugEnabled())
-         {
-            log.debug("collectionPutObject(): aspectized obj is a List type of size: "
-                      + ((List) obj).size());
-         }
-
-         List list = (List) obj;
-
-         // Let's replace it with a proxy if necessary
-         if (!(obj instanceof ClassProxy))
-         {
-            Class clazz = obj.getClass();
-            try
-            {
-               obj = CollectionInterceptorUtil.createListProxy(pCache_, fqn, clazz, (List) obj);
-            }
-            catch (Exception e)
-            {
-               throw new CacheException("failure creating proxy", e);
-            }
-
-            checkListRecursion(list, obj);
-         }
-
-         isCollection = true;
-         // populate via the proxied collection
-         for (Iterator i = list.iterator(); i.hasNext();)
-         {
-            ((List) obj).add(i.next());
-         }
-
-      }
-      else if (obj instanceof Set)
-      {
-         if (log.isDebugEnabled())
-         {
-            log.debug("collectionPutObject(): aspectized obj is a Set type of size: "
-                      + ((Set) obj).size());
-         }
-
-         Set set = (Set) obj;
-
-         // Let's replace it with a proxy if necessary
-         if (!(obj instanceof ClassProxy))
-         {
-            Class clazz = obj.getClass();
-            try
-            {
-               obj = CollectionInterceptorUtil.createSetProxy(pCache_, fqn, clazz, (Set) obj);
-            }
-            catch (Exception e)
-            {
-               throw new CacheException("failure creating proxy", e);
-            }
-
-            checkSetRecursion(set, obj);
-         }
-
-         isCollection = true;
-         // populate via the proxied collection
-         for (Iterator i = set.iterator(); i.hasNext();)
-         {
-            ((Set) obj).add(i.next());
-         }
-
-      }
-
-      if (isCollection)
-      {
-         // Need to reset it here in case this is a new proxy instance
-         pojoInstance.set(obj);
-         // Attach pojoReference to that interceptor
-         BaseInterceptor baseInterceptor = (BaseInterceptor) CollectionInterceptorUtil.getInterceptor(
-               (ClassProxy) obj);
-         baseInterceptor.setAopInstance(pojoInstance);
-      }
-   }
-
-   private void checkListRecursion(List list, Object obj)
-   {
-      while (true)
-      {
-         int i = list.indexOf(list); // check for recursion
-         if (i == -1) break;
-
-         list.remove(list);
-         list.add(i, obj);
-      }
-   }
-
-   private void checkSetRecursion(Set set, Object obj)
-   {
-      if (set.remove(set))
-      {
-         set.add(obj); // replace with proxy
-         throw new PojoCacheException("CollectionClassHandler.checkSetRecursion(): " +
-                                      "detect a recursive set (e.g., set inside the same set). This will fail to " +
-                                      "replicate even outside of PojoCache with HashSet. " + set);
-      }
-   }
-
-   private void checkMapRecursion(Map map, Object obj)
-   {
-      Map m = java.util.Collections.unmodifiableMap(map);
-
-      for (Object k : m.keySet())
-      {
-         if (m == k)
-         {
-            throw new PojoCacheException("CollectionClassHandler.checkMapRecursion(): " +
-                                         " Can't handle the recursion map where it is nested in a constant key " + map);
-         }
-
-         Object v = m.get(k);
-         if (v == map)
-         {
-            throw new PojoCacheException("CollectionClassHandler.checkMapRecursion(): " +
-                                         "detect a recursive map (e.g., map inside the same map). This will fail to " +
-                                         "replicate even outside of PojoCache with HashMap because of hashCode. " + map);
-            // recursion here, replace it with proxy
-//            map.put(k, obj);
-         }
-      }
-   }
-
-   @Override
-   protected Object remove(Fqn<?> fqn, Fqn<?> referencingFqn, Object obj) throws CacheException
-   {
-      if (!(obj instanceof ClassProxy))
-      {
-         throw new PojoCacheException("CollectionClassHandler.collectionRemoveObject(): object is not a proxy :" + obj);
-      }
-
-      AbstractCollectionInterceptor interceptor = (AbstractCollectionInterceptor) CollectionInterceptorUtil.getInterceptor((ClassProxy) obj);
-      // detach the interceptor. This will trigger a copy and remove.
-      (new PojoUtil()).detachCollectionInterceptor(interceptor);
-      cache_.removeNode(fqn);
-
-      return interceptor.getCurrentCopy();
-   }
-
-
-   @Override
-   protected boolean handles(Class<?> clazz)
-   {
-      return Collection.class.isAssignableFrom(clazz) || Map.class.isAssignableFrom(clazz);
-   }
-}

Copied: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/CollectionClassHandler.java (from rev 6374, pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/CollectionClassHandler.java)
===================================================================
--- pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/CollectionClassHandler.java	                        (rev 0)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/CollectionClassHandler.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -0,0 +1,290 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+package org.jboss.cache.pojo.impl;
+
+import java.util.*;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.aop.proxy.ClassProxy;
+import org.jboss.cache.Cache;
+import org.jboss.cache.CacheException;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.pojo.PojoCacheException;
+import org.jboss.cache.pojo.Reference;
+import org.jboss.cache.pojo.collection.CollectionInterceptorUtil;
+import org.jboss.cache.pojo.interceptors.dynamic.AbstractCollectionInterceptor;
+import org.jboss.cache.pojo.interceptors.dynamic.BaseInterceptor;
+
+/**
+ * Handling the Collection class management. Has no consideration of object graph here.
+ *
+ * @author Ben Wang
+ *         Date: Aug 4, 2005
+ * @version $Id$
+ */
+class CollectionClassHandler extends AbstractHandler
+{
+   private final Log log = LogFactory.getLog(CollectionClassHandler.class);
+   private Cache<Object, Object> cache_;
+   private PojoCacheImpl pCache_;
+   private InternalHelper internal_;
+
+   public CollectionClassHandler(PojoCacheImpl pCache, InternalHelper internal)
+   {
+      pCache_ = pCache;
+      cache_ = pCache_.getCache();
+      internal_ = internal;
+   }
+
+   protected Fqn<?> getFqn(Object collection)
+   {
+      if (! (collection instanceof ClassProxy))
+         return null;
+
+      BaseInterceptor interceptor = CollectionInterceptorUtil.getInterceptor((ClassProxy) collection);
+      return interceptor != null ? interceptor.getFqn() : null;
+   }
+
+   protected Object get(Fqn fqn, Class clazz, PojoInstance pojoInstance)
+         throws CacheException
+   {
+      Object obj = null;
+      try
+      {
+         if (Map.class.isAssignableFrom(clazz))
+         {
+            Object map = clazz.newInstance();
+            obj = CollectionInterceptorUtil.createMapProxy(pCache_, fqn, clazz, (Map) map);
+         }
+         else if (List.class.isAssignableFrom(clazz))
+         {
+            Object list = clazz.newInstance();
+            obj = CollectionInterceptorUtil.createListProxy(pCache_, fqn, clazz, (List) list);
+         }
+         else if (Set.class.isAssignableFrom(clazz))
+         {
+            Object set = clazz.newInstance();
+            obj = CollectionInterceptorUtil.createSetProxy(pCache_, fqn, clazz, (Set) set);
+         }
+      }
+      catch (Exception e)
+      {
+         throw new CacheException("failure creating proxy", e);
+      }
+
+      return obj;
+   }
+
+   protected void put(Fqn fqn, Reference reference, Object obj) throws CacheException
+   {
+      boolean isCollection = false;
+
+      CachedType type = null;
+      if (obj instanceof ClassProxy)
+      {
+         throw new IllegalStateException("CollectionClassHandler.put(): obj is an ClassProxy instance " + obj);
+      }
+
+      type = pCache_.getCachedType(obj.getClass());
+
+      //JBCACHE-760: for collection - put initialized aopInstance in fqn
+      if (!(obj instanceof Map || obj instanceof List || obj instanceof Set))
+      {
+         return;
+      }
+
+      // Always initialize the ref count so that we can mark this as an AopNode.
+      PojoInstance pojoInstance = InternalHelper.initializeAopInstance(reference);
+      pojoInstance.set(obj);
+      pojoInstance.setPojoClass(type.getType());
+      cache_.put(fqn, PojoInstance.KEY, pojoInstance);
+
+      if (obj instanceof Map)
+      {
+         if (log.isDebugEnabled())
+         {
+            log.debug("collectionPutObject(): aspectized obj is a Map type of size: " + ((Map) obj).size());
+         }
+
+         // Let's replace it with a proxy if necessary
+         Map map = (Map) obj;
+         if (!(obj instanceof ClassProxy))
+         {
+            Class clazz = obj.getClass();
+            try
+            {
+               obj = CollectionInterceptorUtil.createMapProxy(pCache_, fqn, clazz, (Map) obj);
+            }
+            catch (Exception e)
+            {
+               throw new CacheException("failure creating proxy", e);
+            }
+
+            checkMapRecursion(map, obj);
+         }
+
+         isCollection = true;
+         // populate via the proxied collection
+         for (Iterator i = map.entrySet().iterator(); i.hasNext();)
+         {
+            Map.Entry entry = (Map.Entry) i.next();
+            ((Map) obj).put(entry.getKey(), entry.getValue());
+         }
+
+      }
+      else if (obj instanceof List)
+      {
+         if (log.isDebugEnabled())
+         {
+            log.debug("collectionPutObject(): aspectized obj is a List type of size: "
+                      + ((List) obj).size());
+         }
+
+         List list = (List) obj;
+
+         // Let's replace it with a proxy if necessary
+         if (!(obj instanceof ClassProxy))
+         {
+            Class clazz = obj.getClass();
+            try
+            {
+               obj = CollectionInterceptorUtil.createListProxy(pCache_, fqn, clazz, (List) obj);
+            }
+            catch (Exception e)
+            {
+               throw new CacheException("failure creating proxy", e);
+            }
+
+            checkListRecursion(list, obj);
+         }
+
+         isCollection = true;
+         // populate via the proxied collection
+         for (Iterator i = list.iterator(); i.hasNext();)
+         {
+            ((List) obj).add(i.next());
+         }
+
+      }
+      else if (obj instanceof Set)
+      {
+         if (log.isDebugEnabled())
+         {
+            log.debug("collectionPutObject(): aspectized obj is a Set type of size: "
+                      + ((Set) obj).size());
+         }
+
+         Set set = (Set) obj;
+
+         // Let's replace it with a proxy if necessary
+         if (!(obj instanceof ClassProxy))
+         {
+            Class clazz = obj.getClass();
+            try
+            {
+               obj = CollectionInterceptorUtil.createSetProxy(pCache_, fqn, clazz, (Set) obj);
+            }
+            catch (Exception e)
+            {
+               throw new CacheException("failure creating proxy", e);
+            }
+
+            checkSetRecursion(set, obj);
+         }
+
+         isCollection = true;
+         // populate via the proxied collection
+         for (Iterator i = set.iterator(); i.hasNext();)
+         {
+            ((Set) obj).add(i.next());
+         }
+
+      }
+
+      if (isCollection)
+      {
+         // Need to reset it here in case this is a new proxy instance
+         pojoInstance.set(obj);
+         // Attach pojoReference to that interceptor
+         BaseInterceptor baseInterceptor = (BaseInterceptor) CollectionInterceptorUtil.getInterceptor(
+               (ClassProxy) obj);
+         baseInterceptor.setAopInstance(pojoInstance);
+      }
+   }
+
+   private void checkListRecursion(List list, Object obj)
+   {
+      while (true)
+      {
+         int i = list.indexOf(list); // check for recursion
+         if (i == -1) break;
+
+         list.remove(list);
+         list.add(i, obj);
+      }
+   }
+
+   private void checkSetRecursion(Set set, Object obj)
+   {
+      if (set.remove(set))
+      {
+         set.add(obj); // replace with proxy
+         throw new PojoCacheException("CollectionClassHandler.checkSetRecursion(): " +
+                                      "detect a recursive set (e.g., set inside the same set). This will fail to " +
+                                      "replicate even outside of PojoCache with HashSet. " + set);
+      }
+   }
+
+   private void checkMapRecursion(Map map, Object obj)
+   {
+      Map m = java.util.Collections.unmodifiableMap(map);
+
+      for (Object k : m.keySet())
+      {
+         if (m == k)
+         {
+            throw new PojoCacheException("CollectionClassHandler.checkMapRecursion(): " +
+                                         " Can't handle the recursion map where it is nested in a constant key " + map);
+         }
+
+         Object v = m.get(k);
+         if (v == map)
+         {
+            throw new PojoCacheException("CollectionClassHandler.checkMapRecursion(): " +
+                                         "detect a recursive map (e.g., map inside the same map). This will fail to " +
+                                         "replicate even outside of PojoCache with HashMap because of hashCode. " + map);
+            // recursion here, replace it with proxy
+//            map.put(k, obj);
+         }
+      }
+   }
+
+   @Override
+   protected Object remove(Fqn<?> fqn, Reference referencingFqn, Object obj) throws CacheException
+   {
+      if (!(obj instanceof ClassProxy))
+      {
+         throw new PojoCacheException("CollectionClassHandler.collectionRemoveObject(): object is not a proxy :" + obj);
+      }
+
+      AbstractCollectionInterceptor interceptor = (AbstractCollectionInterceptor) CollectionInterceptorUtil.getInterceptor((ClassProxy) obj);
+      // detach the interceptor. This will trigger a copy and remove.
+      (new PojoUtil()).detachCollectionInterceptor(interceptor);
+      cache_.removeNode(fqn);
+
+      return interceptor.getCurrentCopy();
+   }
+
+
+   @Override
+   protected boolean handles(Class<?> clazz)
+   {
+      return Collection.class.isAssignableFrom(clazz) || Map.class.isAssignableFrom(clazz);
+   }
+}

Deleted: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/InternalHelper.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/InternalHelper.java	2008-07-16 17:30:08 UTC (rev 6310)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/InternalHelper.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -1,416 +0,0 @@
-/*
- * JBoss, the OpenSource J2EE webOS
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package org.jboss.cache.pojo.impl;
-
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.jboss.cache.Cache;
-import org.jboss.cache.CacheException;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.lock.UpgradeException;
-import org.jboss.cache.pojo.PojoCache;
-import org.jboss.cache.pojo.PojoCacheException;
-import org.jboss.cache.pojo.util.ObjectUtil;
-
-/**
- * Internal helper class to handle internal cache sotre, that is, the portion that is not part of
- * user's data.
- *
- * @author Ben Wang
- */
-public class InternalHelper
-{
-   private static  Log log = LogFactory.getLog(InternalHelper.class.getName());
-
-   private Cache<Object, Object> cache;
-   private PojoCache pcache;
-
-   InternalHelper(PojoCache pcache)
-   {
-      this.cache = pcache.getCache();
-      this.pcache = pcache;
-   }
-
-   PojoInstance getPojoInstance(Fqn fqn) throws CacheException
-   {
-      return (PojoInstance) get(fqn, PojoInstance.KEY, true);
-   }
-
-   PojoReference getPojoReference(Fqn fqn, String field) throws CacheException
-   {
-      if (field == null)
-         field = PojoReference.KEY;
-
-      return (PojoReference) get(fqn, field, true);
-   }
-
-   PojoReference getPojoReference(Fqn fqn) throws CacheException
-   {
-      return getPojoReference(fqn, null);
-   }
-
-
-   static PojoInstance initializeAopInstance(Fqn sourceFqn)
-   {
-      PojoInstance pojoInstance = new PojoInstance();
-
-      pojoInstance.incrementRefCount(sourceFqn);
-      return pojoInstance;
-   }
-
-   /**
-    * Increment reference count for the pojo. Note that this is not thread safe or atomic.
-    */
-   int incrementRefCount(Fqn originalFqn, Fqn referencingFqn) throws CacheException
-   {
-      PojoInstance pojoInstance = getPojoInstance(originalFqn);
-      if (pojoInstance == null)
-         throw new PojoCacheException("InternalDelegate.incrementRefCount(): null pojoReference for fqn: " + originalFqn);
-
-      int count = pojoInstance.incrementRefCount(referencingFqn);
-      // need to update it.
-      put(originalFqn, PojoInstance.KEY, pojoInstance);
-      return count;
-   }
-
-   /**
-    * Has a delegate method so we can use the switch.
-    */
-
-   Object get(Fqn fqn, Object key) throws CacheException
-   {
-      return get(fqn, key, false);
-   }
-
-   private Object get(Fqn fqn, Object key, boolean gravitate) throws CacheException
-   {
-      // Only gravitate when we have to and only when the user has enabled it
-      if (gravitate && pcache.getThreadContext().isGravitationEnabled())
-      {
-         cache.getInvocationContext().getOptionOverrides().setForceDataGravitation(true);
-         Object obj = cache.get(fqn, key);
-         cache.getInvocationContext().getOptionOverrides().setForceDataGravitation(false);
-         return obj;
-      }
-
-      return cache.get(fqn, key);
-   }
-
-   private void put(Fqn fqn, Object key, Object value) throws CacheException
-   {
-      cache.put(fqn, key, value);
-   }
-
-   void put(Fqn fqn, Map map) throws CacheException
-   {
-      cache.put(fqn, map);
-   }
-
-
-   /**
-    * decrement reference count for the pojo. Note that this is not thread safe or atomic.
-    */
-   int decrementRefCount(Fqn originalFqn, Fqn referencingFqn) throws CacheException
-   {
-      PojoInstance pojoInstance = getPojoInstance(originalFqn);
-      if (pojoInstance == null)
-         throw new PojoCacheException("InternalDelegate.decrementRefCount(): null pojoReference.");
-
-      int count = pojoInstance.decrementRefCount(referencingFqn);
-
-      if (count < -1)  // can't dip below -1
-         throw new PojoCacheException("InternalDelegate.decrementRefCount(): null pojoReference.");
-
-      // need to update it.
-      put(originalFqn, PojoInstance.KEY, pojoInstance);
-      return count;
-   }
-
-   static boolean isReferenced(PojoInstance pojoInstance)
-   {
-      // If ref counter is greater than 0, we fqn is being referenced.
-      return (pojoInstance.getRefCount() > 0);
-   }
-
-   int getRefCount(Fqn fqn) throws CacheException
-   {
-      return getPojoInstance(fqn).getRefCount();
-   }
-
-   String XgetRefFqn(Fqn fqn) throws CacheException
-   {
-      PojoInstance pojoInstance = getPojoInstance(fqn);
-      return getRefFqn(pojoInstance);
-   }
-
-   String getRefFqn(PojoInstance pojoInstance) throws CacheException
-   {
-      if (pojoInstance == null)
-         return null;
-
-      String aliasFqn = pojoInstance.getInternalFqn();
-
-      if (aliasFqn == null || aliasFqn.length() == 0) return null;
-
-      return getRefFqnFromAlias(aliasFqn);
-   }
-
-   void setRefFqn(Fqn fqn, String internalFqn) throws CacheException
-   {
-      PojoInstance pojoInstance = getPojoInstance(fqn);
-      if (pojoInstance == null)
-         pojoInstance = new PojoInstance();
-
-      pojoInstance.setInternalFqn(internalFqn);
-      put(fqn, PojoInstance.KEY, pojoInstance);
-   }
-
-   void removeRefFqn(Fqn fqn) throws CacheException
-   {
-      PojoInstance pojoInstance = getPojoInstance(fqn);
-      if (pojoInstance == null)
-         throw new PojoCacheException("InternalDelegate.getInternalFqn(): null pojoReference.");
-
-      pojoInstance.removeInternalFqn();
-      put(fqn, PojoInstance.KEY, pojoInstance);
-   }
-
-   Object getPojo(Fqn fqn, String field) throws CacheException
-   {
-      PojoReference pojoReference = getPojoReference(fqn, field);
-      Fqn realFqn = null;
-      if (pojoReference != null)
-      {
-         // This is outward facing node
-         realFqn = pojoReference.getFqn();
-      }
-      else
-      {
-         // If we are looking for a field then there must be a reference
-         if (field != null)
-            return null;
-
-         // This is the internal node.
-         realFqn = fqn;
-      }
-
-      PojoInstance pojoInstance = getPojoInstance(realFqn);
-      if (pojoInstance == null)
-         return null;
-
-      return pojoInstance.get();
-   }
-
-   void setPojo(Fqn fqn, Object pojo) throws CacheException
-   {
-      PojoInstance pojoInstance = getPojoInstance(fqn);
-      if (pojoInstance == null)
-      {
-         pojoInstance = new PojoInstance();
-         put(fqn, PojoInstance.KEY, pojoInstance);
-      }
-
-      pojoInstance.set(pojo);
-      // No need to do a cache put since pojo is transient anyway.
-   }
-
-   static boolean isMultipleReferenced(PojoInstance pojoInstance)
-   {
-      if (pojoInstance.getRefCount() > (PojoInstance.INITIAL_COUNTER_VALUE + 1)) return true;
-
-      return false;
-   }
-
-   static void setPojo(PojoInstance pojoInstance, Object pojo)
-   {
-      // No need to do a cache put since pojo is transient anyway.
-      pojoInstance.set(pojo);
-   }
-
-   void setPojo(Fqn fqn, Object pojo, PojoInstance pojoInstance) throws CacheException
-   {
-      if (pojoInstance == null)
-      {
-         pojoInstance = new PojoInstance();
-         put(fqn, PojoInstance.KEY, pojoInstance);
-      }
-
-      pojoInstance.set(pojo);
-      // No need to do a cache put since pojo is transient anyway.
-   }
-
-   void putPojoReference(Fqn fqn, PojoReference pojoReference) throws CacheException
-   {
-      putPojoReference(fqn, pojoReference, PojoReference.KEY);
-   }
-
-   void putPojoReference(Fqn fqn, PojoReference pojoReference, String field) throws CacheException
-   {
-      if (field == null)
-         field = PojoReference.KEY;
-
-      put(fqn, field, pojoReference);
-   }
-
-   void putAopClazz(Fqn fqn, Class clazz) throws CacheException
-   {
-      put(fqn, InternalConstant.CLASS_INTERNAL, clazz);
-   }
-
-   /**
-    * We store the class name in string and put it in map instead of directly putting
-    * it into cache for optimization.
-    */
-   static void putAopClazz(Class clazz, Map map)
-   {
-      map.put(InternalConstant.CLASS_INTERNAL, clazz);
-   }
-
-   Class peekAopClazz(Fqn fqn) throws CacheException
-   {
-      return (Class) get(fqn, InternalConstant.CLASS_INTERNAL);
-   }
-
-   void removeInternalAttributes(Fqn fqn) throws CacheException
-   {
-      cache.remove(fqn, PojoInstance.KEY);
-      cache.remove(fqn, InternalConstant.CLASS_INTERNAL);
-   }
-
-   void cleanUp(Fqn fqn, String field) throws CacheException
-   {
-      if (field != null)
-      {
-         cache.remove(fqn, field);
-         return;
-      }
-
-      // We can't do a brute force remove anymore?
-      if (cache.getRoot().getChild(fqn).getChildren().size() == 0)
-      {
-         // remove everything
-         cache.removeNode(fqn);
-//         cache_.getRoot().getChild(fqn).clearData();
-//         removeNodeWithoutInterceptor(fqn);
-      }
-      else
-      {
-         // Assume everything here is all PojoCache data for optimization
-         cache.getRoot().getChild(fqn).clearData();
-         if (log.isTraceEnabled())
-         {
-            log.trace("cleanup(): fqn: " + fqn + " is not empty. That means it has sub-pojos. Will not remove node");
-         }
-      }
-   }
-
-   String createIndirectFqn(String fqn) throws CacheException
-   {
-      String indirectFqn = getIndirectFqn(fqn);
-      Fqn internalFqn = getInternalFqn(fqn);
-      put(internalFqn, indirectFqn, fqn);
-      return indirectFqn;
-   }
-
-   private Fqn getInternalFqn(String fqn)
-   {
-      if (fqn == null || fqn.length() == 0)
-         throw new IllegalStateException("InternalDelegate.getInternalFqn(). fqn is either null or empty!");
-
-      String indirectFqn = getIndirectFqn(fqn);
-      return new Fqn(InternalConstant.JBOSS_INTERNAL_MAP, indirectFqn);
-//      return JBOSS_INTERNAL_MAP;
-   }
-
-   static String getIndirectFqn(String fqn)
-   {
-      // TODO This is not unique. Will need to come up with a better one in the future.
-      return ObjectUtil.getIndirectFqn(fqn);
-   }
-
-   void removeIndirectFqn(String oldFqn) throws CacheException
-   {
-      String indirectFqn = getIndirectFqn(oldFqn);
-      cache.remove(getInternalFqn(oldFqn), indirectFqn);
-   }
-
-   void setIndirectFqn(String oldFqn, String newFqn) throws CacheException
-   {
-      String indirectFqn = getIndirectFqn(oldFqn);
-      Fqn tmpFqn = getInternalFqn(oldFqn);
-      put(tmpFqn, indirectFqn, newFqn);
-   }
-
-   void updateIndirectFqn(Fqn originalFqn, Fqn newFqn) throws CacheException
-   {
-      put(getInternalFqn(originalFqn.toString()), getIndirectFqn(originalFqn.toString()), newFqn.toString());
-   }
-
-   private String getRefFqnFromAlias(String aliasFqn) throws CacheException
-   {
-      return (String) get(getInternalFqn(aliasFqn), aliasFqn, true);
-   }
-
-   Fqn getNextFqnInLine(Fqn currentFqn) throws CacheException
-   {
-      PojoInstance ai = getPojoInstance(currentFqn);
-      return ai.getAndRemoveFirstFqnInList();
-   }
-
-   /**
-    * Test if this internal node.
-    *
-    * @param fqn
-    */
-   public static boolean isInternalNode(Fqn fqn)
-   {
-      // we ignore all the node events corresponding to JBOSS_INTERNAL
-      if (fqn.isChildOrEquals(InternalConstant.JBOSS_INTERNAL)) return true;
-
-      return false;
-   }
-
-   public boolean lockPojo(Fqn id) throws CacheException
-   {
-      final int RETRY = 5;
-
-      if (log.isDebugEnabled())
-         log.debug("lockPojo(): id:" + id);
-
-      boolean isNeeded = true;
-      int retry = 0;
-
-      while (isNeeded)
-      {
-         try
-         {
-            cache.put(id, InternalConstant.POJOCACHE_LOCK, "LOCK");
-            isNeeded = false;
-         }
-         catch (UpgradeException upe)
-         {
-            log.warn("lockPojo(): can't upgrade the lock during lockPojo. Will re-try. id: " + id
-                     + " retry times: " + retry);
-            if (retry++ > RETRY)
-               return false;
-
-            // try to sleep a little as well.
-            try
-            {
-               Thread.sleep(10);
-            }
-            catch (InterruptedException e)
-            {
-            }
-         }
-      }
-
-      return true;
-   }
-}
\ No newline at end of file

Copied: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/InternalHelper.java (from rev 6374, pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/InternalHelper.java)
===================================================================
--- pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/InternalHelper.java	                        (rev 0)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/InternalHelper.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -0,0 +1,365 @@
+/*
+ * JBoss, the OpenSource J2EE webOS
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jboss.cache.pojo.impl;
+
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.*;
+import org.jboss.cache.lock.UpgradeException;
+import org.jboss.cache.pojo.*;
+import org.jboss.cache.pojo.util.ObjectUtil;
+
+/**
+ * Internal helper class to handle internal cache sotre, that is, the portion that is not part of
+ * user's data.
+ *
+ * @author Ben Wang
+ */
+public class InternalHelper
+{
+   private static  Log log = LogFactory.getLog(InternalHelper.class.getName());
+
+   private Cache<Object, Object> cache;
+   private PojoCache pcache;
+
+   InternalHelper(PojoCache pcache)
+   {
+      this.cache = pcache.getCache();
+      this.pcache = pcache;
+   }
+
+   PojoInstance getPojoInstance(Fqn fqn) throws CacheException
+   {
+      return (PojoInstance) get(fqn, PojoInstance.KEY, true);
+   }
+
+   PojoReference getPojoReference(Fqn fqn, String field) throws CacheException
+   {
+      if (field == null)
+         field = PojoReference.KEY;
+
+      return (PojoReference) get(fqn, field, true);
+   }
+
+   PojoReference getPojoReference(Fqn fqn) throws CacheException
+   {
+      return getPojoReference(fqn, null);
+   }
+
+
+   static PojoInstance initializeAopInstance(Reference reference)
+   {
+      PojoInstance pojoInstance = new PojoInstance();
+
+      pojoInstance.incrementRefCount(reference);
+      return pojoInstance;
+   }
+
+   /**
+    * Increment reference count for the pojo. Note that this is not thread safe or atomic.
+    * @param reference TODO
+    */
+   int incrementRefCount(Fqn originalFqn, Reference reference) throws CacheException
+   {
+      PojoInstance pojoInstance = getPojoInstance(originalFqn);
+      if (pojoInstance == null)
+         throw new PojoCacheException("InternalDelegate.incrementRefCount(): null pojoReference for fqn: " + originalFqn);
+
+      int count = pojoInstance.incrementRefCount(reference);
+      // need to update it.
+      put(originalFqn, PojoInstance.KEY, pojoInstance);
+      return count;
+   }
+
+   /**
+    * Has a delegate method so we can use the switch.
+    */
+
+   Object get(Fqn fqn, Object key) throws CacheException
+   {
+      return get(fqn, key, false);
+   }
+
+   private Object get(Fqn fqn, Object key, boolean gravitate) throws CacheException
+   {
+      // Only gravitate when we have to and only when the user has enabled it
+      if (gravitate && pcache.getThreadContext().isGravitationEnabled())
+      {
+         cache.getInvocationContext().getOptionOverrides().setForceDataGravitation(true);
+         Object obj = cache.get(fqn, key);
+         cache.getInvocationContext().getOptionOverrides().setForceDataGravitation(false);
+         return obj;
+      }
+
+      return cache.get(fqn, key);
+   }
+
+   private void put(Fqn fqn, Object key, Object value) throws CacheException
+   {
+      cache.put(fqn, key, value);
+   }
+
+   void put(Fqn fqn, Map map) throws CacheException
+   {
+      cache.put(fqn, map);
+   }
+
+
+   /**
+    * decrement reference count for the pojo. Note that this is not thread safe or atomic.
+    */
+   int decrementRefCount(Fqn originalFqn, Reference reference) throws CacheException
+   {
+      PojoInstance pojoInstance = getPojoInstance(originalFqn);
+      if (pojoInstance == null)
+         throw new PojoCacheException("InternalDelegate.decrementRefCount(): null pojoReference.");
+
+      int count = pojoInstance.decrementRefCount(reference);
+
+      if (count < -1)  // can't dip below -1
+         throw new PojoCacheException("InternalDelegate.decrementRefCount(): null pojoReference.");
+
+      // need to update it.
+      put(originalFqn, PojoInstance.KEY, pojoInstance);
+      return count;
+   }
+
+   static boolean isReferenced(PojoInstance pojoInstance)
+   {
+      // If ref counter is greater than 0, we fqn is being referenced.
+      return (pojoInstance.getRefCount() > 0);
+   }
+
+   Object getPojo(Fqn fqn, String field) throws CacheException
+   {
+      PojoReference pojoReference = getPojoReference(fqn, field);
+      Fqn realFqn = null;
+      if (pojoReference != null)
+      {
+         // This is outward facing node
+         realFqn = pojoReference.getFqn();
+      }
+      else
+      {
+         // If we are looking for a field then there must be a reference
+         if (field != null)
+            return null;
+
+         // This is the internal node.
+         realFqn = fqn;
+      }
+
+      PojoInstance pojoInstance = getPojoInstance(realFqn);
+      if (pojoInstance == null)
+         return null;
+
+      return pojoInstance.get();
+   }
+
+   void setPojo(Fqn fqn, Object pojo) throws CacheException
+   {
+      PojoInstance pojoInstance = getPojoInstance(fqn);
+      if (pojoInstance == null)
+      {
+         pojoInstance = new PojoInstance();
+         put(fqn, PojoInstance.KEY, pojoInstance);
+      }
+
+      pojoInstance.set(pojo);
+      // No need to do a cache put since pojo is transient anyway.
+   }
+
+   static boolean isMultipleReferenced(PojoInstance pojoInstance)
+   {
+      if (pojoInstance.getRefCount() > (PojoInstance.INITIAL_COUNTER_VALUE + 1)) return true;
+
+      return false;
+   }
+
+   static void setPojo(PojoInstance pojoInstance, Object pojo)
+   {
+      // No need to do a cache put since pojo is transient anyway.
+      pojoInstance.set(pojo);
+   }
+
+   void setPojo(Fqn fqn, Object pojo, PojoInstance pojoInstance) throws CacheException
+   {
+      if (pojoInstance == null)
+      {
+         pojoInstance = new PojoInstance();
+         put(fqn, PojoInstance.KEY, pojoInstance);
+      }
+
+      pojoInstance.set(pojo);
+      // No need to do a cache put since pojo is transient anyway.
+   }
+
+   void putPojoReference(Fqn fqn, PojoReference pojoReference) throws CacheException
+   {
+      putPojoReference(fqn, pojoReference, PojoReference.KEY);
+   }
+
+   void putPojoReference(Fqn fqn, PojoReference pojoReference, String field) throws CacheException
+   {
+      if (field == null)
+         field = PojoReference.KEY;
+
+      put(fqn, field, pojoReference);
+   }
+
+   void putAopClazz(Fqn fqn, Class clazz) throws CacheException
+   {
+      put(fqn, InternalConstant.CLASS_INTERNAL, clazz);
+   }
+
+   /**
+    * We store the class name in string and put it in map instead of directly putting
+    * it into cache for optimization.
+    */
+   static void putAopClazz(Class clazz, Map map)
+   {
+      map.put(InternalConstant.CLASS_INTERNAL, clazz);
+   }
+
+   Class peekAopClazz(Fqn fqn) throws CacheException
+   {
+      return (Class) get(fqn, InternalConstant.CLASS_INTERNAL);
+   }
+
+   void removeInternalAttributes(Fqn fqn) throws CacheException
+   {
+      cache.remove(fqn, PojoInstance.KEY);
+      cache.remove(fqn, InternalConstant.CLASS_INTERNAL);
+   }
+
+   void cleanUp(Fqn fqn, String field) throws CacheException
+   {
+      if (field != null)
+      {
+         cache.remove(fqn, field);
+         return;
+      }
+
+      // We can't do a brute force remove anymore?
+      if (cache.getRoot().getChild(fqn).getChildren().size() == 0)
+      {
+         // remove everything
+         cache.removeNode(fqn);
+//         cache_.getRoot().getChild(fqn).clearData();
+//         removeNodeWithoutInterceptor(fqn);
+      }
+      else
+      {
+         // Assume everything here is all PojoCache data for optimization
+         cache.getRoot().getChild(fqn).clearData();
+         if (log.isTraceEnabled())
+         {
+            log.trace("cleanup(): fqn: " + fqn + " is not empty. That means it has sub-pojos. Will not remove node");
+         }
+      }
+   }
+
+   String createIndirectFqn(String fqn) throws CacheException
+   {
+      String indirectFqn = getIndirectFqn(fqn);
+      Fqn internalFqn = getInternalFqn(fqn);
+      put(internalFqn, indirectFqn, fqn);
+      return indirectFqn;
+   }
+
+   private Fqn getInternalFqn(String fqn)
+   {
+      if (fqn == null || fqn.length() == 0)
+         throw new IllegalStateException("InternalDelegate.getInternalFqn(). fqn is either null or empty!");
+
+      String indirectFqn = getIndirectFqn(fqn);
+      return new Fqn(InternalConstant.JBOSS_INTERNAL_MAP, indirectFqn);
+//      return JBOSS_INTERNAL_MAP;
+   }
+
+   static String getIndirectFqn(String fqn)
+   {
+      // TODO This is not unique. Will need to come up with a better one in the future.
+      return ObjectUtil.getIndirectFqn(fqn);
+   }
+
+   void removeIndirectFqn(String oldFqn) throws CacheException
+   {
+      String indirectFqn = getIndirectFqn(oldFqn);
+      cache.remove(getInternalFqn(oldFqn), indirectFqn);
+   }
+
+   void setIndirectFqn(String oldFqn, String newFqn) throws CacheException
+   {
+      String indirectFqn = getIndirectFqn(oldFqn);
+      Fqn tmpFqn = getInternalFqn(oldFqn);
+      put(tmpFqn, indirectFqn, newFqn);
+   }
+
+   void updateIndirectFqn(Fqn originalFqn, Fqn newFqn) throws CacheException
+   {
+      put(getInternalFqn(originalFqn.toString()), getIndirectFqn(originalFqn.toString()), newFqn.toString());
+   }
+
+   private String getRefFqnFromAlias(String aliasFqn) throws CacheException
+   {
+      return (String) get(getInternalFqn(aliasFqn), aliasFqn, true);
+   }
+
+   /**
+    * Test if this internal node.
+    *
+    * @param fqn
+    */
+   public static boolean isInternalNode(Fqn fqn)
+   {
+      // we ignore all the node events corresponding to JBOSS_INTERNAL
+      if (fqn.isChildOrEquals(InternalConstant.JBOSS_INTERNAL)) return true;
+
+      return false;
+   }
+
+   public boolean lockPojo(Fqn id) throws CacheException
+   {
+      final int RETRY = 5;
+
+      if (log.isDebugEnabled())
+         log.debug("lockPojo(): id:" + id);
+
+      boolean isNeeded = true;
+      int retry = 0;
+
+      while (isNeeded)
+      {
+         try
+         {
+            cache.put(id, InternalConstant.POJOCACHE_LOCK, "LOCK");
+            isNeeded = false;
+         }
+         catch (UpgradeException upe)
+         {
+            log.warn("lockPojo(): can't upgrade the lock during lockPojo. Will re-try. id: " + id
+                     + " retry times: " + retry);
+            if (retry++ > RETRY)
+               return false;
+
+            // try to sleep a little as well.
+            try
+            {
+               Thread.sleep(10);
+            }
+            catch (InterruptedException e)
+            {
+            }
+         }
+      }
+
+      return true;
+   }
+}
\ No newline at end of file

Deleted: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/MethodDeclarations.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/MethodDeclarations.java	2008-07-16 17:30:08 UTC (rev 6310)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/MethodDeclarations.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -1,88 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-
-package org.jboss.cache.pojo.impl;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.List;
-
-import org.jboss.aop.InstanceAdvisor;
-import org.jboss.aop.advice.Interceptor;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.pojo.collection.CachedArray;
-import org.jboss.cache.pojo.interceptors.dynamic.AbstractCollectionInterceptor;
-
-/**
- * Method declarations for rollback method mostly.
- *
- * @author Ben Wang
- * @version $Revision$
- */
-public class MethodDeclarations
-{
-   public static final Method attachInterceptor;
-   public static final Method detachInterceptor;
-   public static final Method detachCollectionInterceptor;
-   public static final Method undoAttachInterceptor;
-   public static final Method undoDetachInterceptor;
-   public static final Method undoDetachCollectionInterceptor;
-   ;
-   public static final Method inMemorySubstitution;
-   ;
-   public static final Method undoInMemorySubstitution;
-   ;
-   public static final Method incrementReferenceCount;
-   public static final Method decrementReferenceCount;
-   public static final Method undoIncrementReferenceCount;
-   public static final Method undoDecrementReferenceCount;
-   public static final Method attachArray;
-   public static final Method detachArray;
-   public static final Method undoAttachArray;
-   public static final Method undoDetachArray;
-
-   static
-   {
-      try
-      {
-         attachInterceptor = PojoUtil.class.getDeclaredMethod("attachInterceptor",
-                                                              new Class[]{Object.class, InstanceAdvisor.class, Interceptor.class});
-         detachInterceptor = PojoUtil.class.getDeclaredMethod("detachInterceptor",
-                                                              new Class[]{InstanceAdvisor.class, Interceptor.class});
-         detachCollectionInterceptor = PojoUtil.class.getDeclaredMethod("detachCollectionInterceptor",
-               new Class[]{AbstractCollectionInterceptor.class});
-
-         undoAttachInterceptor = PojoUtil.class.getDeclaredMethod("undoAttachInterceptor",
-                                                                  new Class[]{Object.class, InstanceAdvisor.class, Interceptor.class});
-         undoDetachInterceptor = PojoUtil.class.getDeclaredMethod("undoDetachInterceptor",
-                                                                  new Class[]{InstanceAdvisor.class, Interceptor.class});
-         undoDetachCollectionInterceptor = PojoUtil.class.getDeclaredMethod("undoDetachCollectionInterceptor",
-               new Class[]{AbstractCollectionInterceptor.class});
-         inMemorySubstitution = PojoUtil.class.getDeclaredMethod("inMemorySubstitution",
-                                                                 new Class[]{Object.class, Field.class, Object.class});
-         undoInMemorySubstitution = PojoUtil.class.getDeclaredMethod("undoInMemorySubstitution",
-                                                                     new Class[]{Object.class, Field.class, Object.class});
-         incrementReferenceCount = PojoUtil.class.getDeclaredMethod("incrementReferenceCount",
-                                                                    new Class[]{Fqn.class, int.class, List.class});
-         decrementReferenceCount = PojoUtil.class.getDeclaredMethod("decrementReferenceCount",
-                                                                    new Class[]{Fqn.class, int.class, List.class});
-         undoIncrementReferenceCount = PojoUtil.class.getDeclaredMethod("undoIncrementReferenceCount",
-                                                                        new Class[]{Fqn.class, int.class, List.class});
-         undoDecrementReferenceCount = PojoUtil.class.getDeclaredMethod("undoDecrementReferenceCount",
-                                                                        new Class[]{Fqn.class, int.class, List.class});
-
-         attachArray = PojoUtil.class.getDeclaredMethod("attachArray", new Class[]{Object.class, CachedArray.class});
-         detachArray = PojoUtil.class.getDeclaredMethod("detachArray", new Class[]{Object.class, CachedArray.class});
-         undoAttachArray = PojoUtil.class.getDeclaredMethod("undoAttachArray", new Class[]{Object.class, CachedArray.class});
-         undoDetachArray = PojoUtil.class.getDeclaredMethod("undoDetachArray", new Class[]{Object.class, CachedArray.class});
-      }
-      catch (NoSuchMethodException e)
-      {
-         throw new ExceptionInInitializerError(e);
-      }
-   }
-}

Copied: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/MethodDeclarations.java (from rev 6374, pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/MethodDeclarations.java)
===================================================================
--- pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/MethodDeclarations.java	                        (rev 0)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/MethodDeclarations.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -0,0 +1,88 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+package org.jboss.cache.pojo.impl;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Set;
+
+import org.jboss.aop.InstanceAdvisor;
+import org.jboss.aop.advice.Interceptor;
+import org.jboss.cache.pojo.Reference;
+import org.jboss.cache.pojo.collection.CachedArray;
+import org.jboss.cache.pojo.interceptors.dynamic.AbstractCollectionInterceptor;
+
+/**
+ * Method declarations for rollback method mostly.
+ *
+ * @author Ben Wang
+ * @version $Revision$
+ */
+public class MethodDeclarations
+{
+   public static final Method attachInterceptor;
+   public static final Method detachInterceptor;
+   public static final Method detachCollectionInterceptor;
+   public static final Method undoAttachInterceptor;
+   public static final Method undoDetachInterceptor;
+   public static final Method undoDetachCollectionInterceptor;
+   ;
+   public static final Method inMemorySubstitution;
+   ;
+   public static final Method undoInMemorySubstitution;
+   ;
+   public static final Method incrementReferenceCount;
+   public static final Method decrementReferenceCount;
+   public static final Method undoIncrementReferenceCount;
+   public static final Method undoDecrementReferenceCount;
+   public static final Method attachArray;
+   public static final Method detachArray;
+   public static final Method undoAttachArray;
+   public static final Method undoDetachArray;
+
+   static
+   {
+      try
+      {
+         attachInterceptor = PojoUtil.class.getDeclaredMethod("attachInterceptor",
+                                                              new Class[]{Object.class, InstanceAdvisor.class, Interceptor.class});
+         detachInterceptor = PojoUtil.class.getDeclaredMethod("detachInterceptor",
+                                                              new Class[]{InstanceAdvisor.class, Interceptor.class});
+         detachCollectionInterceptor = PojoUtil.class.getDeclaredMethod("detachCollectionInterceptor",
+               new Class[]{AbstractCollectionInterceptor.class});
+
+         undoAttachInterceptor = PojoUtil.class.getDeclaredMethod("undoAttachInterceptor",
+                                                                  new Class[]{Object.class, InstanceAdvisor.class, Interceptor.class});
+         undoDetachInterceptor = PojoUtil.class.getDeclaredMethod("undoDetachInterceptor",
+                                                                  new Class[]{InstanceAdvisor.class, Interceptor.class});
+         undoDetachCollectionInterceptor = PojoUtil.class.getDeclaredMethod("undoDetachCollectionInterceptor",
+               new Class[]{AbstractCollectionInterceptor.class});
+         inMemorySubstitution = PojoUtil.class.getDeclaredMethod("inMemorySubstitution",
+                                                                 new Class[]{Object.class, Field.class, Object.class});
+         undoInMemorySubstitution = PojoUtil.class.getDeclaredMethod("undoInMemorySubstitution",
+                                                                     new Class[]{Object.class, Field.class, Object.class});
+         incrementReferenceCount = PojoUtil.class.getDeclaredMethod("incrementReferenceCount",
+                                                                    new Class[]{Reference.class, int.class, Set.class});
+         decrementReferenceCount = PojoUtil.class.getDeclaredMethod("decrementReferenceCount",
+                                                                    new Class[]{Reference.class, int.class, Set.class});
+         undoIncrementReferenceCount = PojoUtil.class.getDeclaredMethod("undoIncrementReferenceCount",
+                                                                        new Class[]{Reference.class, int.class, Set.class});
+         undoDecrementReferenceCount = PojoUtil.class.getDeclaredMethod("undoDecrementReferenceCount",
+                                                                        new Class[]{Reference.class, int.class, Set.class});
+
+         attachArray = PojoUtil.class.getDeclaredMethod("attachArray", new Class[]{Object.class, CachedArray.class});
+         detachArray = PojoUtil.class.getDeclaredMethod("detachArray", new Class[]{Object.class, CachedArray.class});
+         undoAttachArray = PojoUtil.class.getDeclaredMethod("undoAttachArray", new Class[]{Object.class, CachedArray.class});
+         undoDetachArray = PojoUtil.class.getDeclaredMethod("undoDetachArray", new Class[]{Object.class, CachedArray.class});
+      }
+      catch (NoSuchMethodException e)
+      {
+         throw new ExceptionInInitializerError(e);
+      }
+   }
+}

Deleted: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/NotificationDispatcher.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/NotificationDispatcher.java	2008-07-16 17:30:08 UTC (rev 6310)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/NotificationDispatcher.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -1,268 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-
-package org.jboss.cache.pojo.impl;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.regex.Pattern;
-
-import org.jboss.cache.Fqn;
-import org.jboss.cache.pojo.PojoCacheException;
-import org.jboss.cache.pojo.notification.annotation.ArrayModified;
-import org.jboss.cache.pojo.notification.annotation.Attached;
-import org.jboss.cache.pojo.notification.annotation.Detached;
-import org.jboss.cache.pojo.notification.annotation.FieldModified;
-import org.jboss.cache.pojo.notification.annotation.ListModified;
-import org.jboss.cache.pojo.notification.annotation.MapModified;
-import org.jboss.cache.pojo.notification.annotation.PojoCacheListener;
-import org.jboss.cache.pojo.notification.annotation.SetModified;
-import org.jboss.cache.pojo.notification.annotation.TransactionCompleted;
-import org.jboss.cache.pojo.notification.annotation.TransactionRegistered;
-import org.jboss.cache.pojo.notification.event.ArrayModifiedEvent;
-import org.jboss.cache.pojo.notification.event.AttachedEvent;
-import org.jboss.cache.pojo.notification.event.DetachedEvent;
-import org.jboss.cache.pojo.notification.event.Event;
-import org.jboss.cache.pojo.notification.event.FieldModifiedEvent;
-import org.jboss.cache.pojo.notification.event.ListModifiedEvent;
-import org.jboss.cache.pojo.notification.event.MapModifiedEvent;
-import org.jboss.cache.pojo.notification.event.SetModifiedEvent;
-import org.jboss.cache.pojo.notification.event.TransactionCompletedEvent;
-import org.jboss.cache.pojo.notification.event.TransactionRegisteredEvent;
-
-// $Id$
-
-/**
- * Dispatches notification events to POJO cache listeners.
- *
- * @author Jason T. Greene
- * @revision $Id$
- */
-class NotificationDispatcher
-{
-   private final static Map<Class<? extends Annotation>, Class<? extends Event>> annotations = new HashMap<Class<? extends Annotation>, Class<? extends Event>>();
-   private final Set<Entry> listeners = new CopyOnWriteArraySet<Entry>();
-   private Set<Object> filteredListeners = new HashSet<Object>();
-   private volatile boolean hasFilters;
-
-   static
-   {
-      annotations.put(Attached.class, AttachedEvent.class);
-      annotations.put(Detached.class, DetachedEvent.class);
-      annotations.put(FieldModified.class, FieldModifiedEvent.class);
-      annotations.put(ListModified.class, ListModifiedEvent.class);
-      annotations.put(MapModified.class, MapModifiedEvent.class);
-      annotations.put(SetModified.class, SetModifiedEvent.class);
-      annotations.put(ArrayModified.class, ArrayModifiedEvent.class);
-      annotations.put(TransactionRegistered.class, TransactionRegisteredEvent.class);
-      annotations.put(TransactionCompleted.class, TransactionCompletedEvent.class);
-   }
-
-   final static class Entry
-   {
-      private final Object listener;
-      private final Pattern pattern;
-      private final Map<Class<?>, List<Method>> notifiers;
-
-      private Entry(Object listener, boolean build)
-      {
-         this(listener, build, null);
-      }
-
-      private Entry(Object listener, boolean build, Pattern pattern)
-      {
-         if (listener == null)
-            throw new IllegalArgumentException("Listener can't be null");
-
-         this.listener = listener;
-         this.pattern = pattern;
-
-         this.notifiers = build ? buildNotifiers(listener.getClass()) : null;
-      }
-
-      // equality is confined to listener
-      public int hashCode()
-      {
-         return listener.hashCode();
-      }
-
-      // equality is confined to listener
-      public boolean equals(Object o)
-      {
-         if (o == this)
-            return true;
-         if (! (o instanceof Entry))
-            return false;
-
-         // Must be the same instance
-         return ((Entry)o).listener == this.listener;
-      }
-
-      private static Map<Class<?>, List<Method>> buildNotifiers(Class clazz)
-      {
-         if (! Modifier.isPublic(clazz.getModifiers()))
-            throw new IllegalArgumentException("Listener must be public! Class:" + clazz.getName());
-
-         if (! clazz.isAnnotationPresent(PojoCacheListener.class))
-            throw new IllegalArgumentException("Not a listener, class did not contain @PojoCacheListener. Class: " + clazz.getName());
-
-
-         Map<Class<?>, List<Method>> notifiers = new HashMap<Class<?>, List<Method>>();
-         for (Method method : clazz.getMethods())
-         {
-            for (Annotation annotation : method.getAnnotations())
-            {
-               Class<? extends Event> event = annotations.get(annotation.annotationType());
-               if (event == null)
-                  continue;
-
-               Class<?>[] types = method.getParameterTypes();
-               if (types.length != 1 || !types[0].isAssignableFrom(event))
-               {
-                  throw new IllegalArgumentException("Listener has invlaid method signature for annotation. " +
-                        "Method: \"" + method.getName() + "\" " +
-                        "Annotation: \"" + annotation.annotationType().getSimpleName() + "\" " +
-                        "Expected Parameter: \"" + event.getSimpleName() + "\"");
-               }
-
-               List<Method> list = notifiers.get(event);
-               if (list == null)
-               {
-                  list = new ArrayList<Method>();
-                  notifiers.put(event, list);
-               }
-
-               list.add(method);
-            }
-         }
-
-         return notifiers;
-      }
-   }
-
-   void add(Object listener)
-   {
-      listeners.add(new Entry(listener, true));
-   }
-
-   // gaurds filteredListeners
-   synchronized void add(Object listener, Pattern pattern)
-   {
-      listeners.add(new Entry(listener, true, pattern));
-      filteredListeners.add(listener);
-      hasFilters = true;
-   }
-
-   // gaurds filteredListeners
-   synchronized void remove(Object listener)
-   {
-      filteredListeners.remove(listener);
-      if (filteredListeners.size() == 0)
-         hasFilters = false;
-      listeners.remove(new Entry(listener, false));
-   }
-
-   boolean hasFilters()
-   {
-      return hasFilters;
-   }
-
-   Set<Object> getListeners()
-   {
-      Set<Object> set = new HashSet<Object>();
-      for (Entry entry : listeners)
-         set.add(entry.listener);
-
-      return Collections.unmodifiableSet(set);
-   }
-
-   Set<Entry> getListenerEntries(List<Fqn> fqns)
-   {
-      Set<Entry> set = new HashSet<Entry>();
-      for (Entry entry : listeners)
-      {
-         if (entry.pattern == null)
-         {
-            set.add(entry);
-            continue;
-         }
-
-         for (Fqn fqn : fqns)
-         {
-            if (entry.pattern.matcher(fqn.toString()).matches())
-            {
-               set.add(entry);
-               break;
-            }
-         }
-      }
-
-      return set;
-   }
-
-   boolean isEmpty()
-   {
-      return listeners.size() == 0;
-   }
-
-   void dispatch(Event notification)
-   {
-      for (Entry entry : listeners)
-      {
-         // Prevent dispatch to filtered entries
-         if (entry.pattern == null)
-            dispatch(notification, entry);
-      }
-   }
-
-   void dispatch(Event notification, Set<Entry> listeners)
-   {
-      for (Entry listener : listeners)
-         dispatch(notification, listener);
-   }
-
-   private void dispatch(Event notification, Entry entry)
-   {
-      List<Method> methods = entry.notifiers.get(notification.getClass());
-      if (methods == null)
-         return;
-
-      try
-      {
-         for (Method method : methods)
-            method.invoke(entry.listener, notification);
-      }
-      catch (Exception e)
-      {
-         throw new PojoCacheException(e);
-      }
-   }
-}

Copied: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/NotificationDispatcher.java (from rev 6551, pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/NotificationDispatcher.java)
===================================================================
--- pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/NotificationDispatcher.java	                        (rev 0)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/NotificationDispatcher.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -0,0 +1,263 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+
+package org.jboss.cache.pojo.impl;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.*;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.regex.Pattern;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.pojo.PojoCacheException;
+import org.jboss.cache.pojo.Reference;
+import org.jboss.cache.pojo.notification.annotation.ArrayModified;
+import org.jboss.cache.pojo.notification.annotation.Attached;
+import org.jboss.cache.pojo.notification.annotation.Detached;
+import org.jboss.cache.pojo.notification.annotation.FieldModified;
+import org.jboss.cache.pojo.notification.annotation.ListModified;
+import org.jboss.cache.pojo.notification.annotation.MapModified;
+import org.jboss.cache.pojo.notification.annotation.PojoCacheListener;
+import org.jboss.cache.pojo.notification.annotation.SetModified;
+import org.jboss.cache.pojo.notification.annotation.TransactionCompleted;
+import org.jboss.cache.pojo.notification.annotation.TransactionRegistered;
+import org.jboss.cache.pojo.notification.event.ArrayModifiedEvent;
+import org.jboss.cache.pojo.notification.event.AttachedEvent;
+import org.jboss.cache.pojo.notification.event.DetachedEvent;
+import org.jboss.cache.pojo.notification.event.Event;
+import org.jboss.cache.pojo.notification.event.FieldModifiedEvent;
+import org.jboss.cache.pojo.notification.event.ListModifiedEvent;
+import org.jboss.cache.pojo.notification.event.MapModifiedEvent;
+import org.jboss.cache.pojo.notification.event.SetModifiedEvent;
+import org.jboss.cache.pojo.notification.event.TransactionCompletedEvent;
+import org.jboss.cache.pojo.notification.event.TransactionRegisteredEvent;
+
+// $Id$
+
+/**
+ * Dispatches notification events to POJO cache listeners.
+ *
+ * @author Jason T. Greene
+ * @revision $Id$
+ */
+class NotificationDispatcher
+{
+   private final static Map<Class<? extends Annotation>, Class<? extends Event>> annotations = new HashMap<Class<? extends Annotation>, Class<? extends Event>>();
+   private final Set<Entry> listeners = new CopyOnWriteArraySet<Entry>();
+   private Set<Object> filteredListeners = new HashSet<Object>();
+   private volatile boolean hasFilters;
+
+   static
+   {
+      annotations.put(Attached.class, AttachedEvent.class);
+      annotations.put(Detached.class, DetachedEvent.class);
+      annotations.put(FieldModified.class, FieldModifiedEvent.class);
+      annotations.put(ListModified.class, ListModifiedEvent.class);
+      annotations.put(MapModified.class, MapModifiedEvent.class);
+      annotations.put(SetModified.class, SetModifiedEvent.class);
+      annotations.put(ArrayModified.class, ArrayModifiedEvent.class);
+      annotations.put(TransactionRegistered.class, TransactionRegisteredEvent.class);
+      annotations.put(TransactionCompleted.class, TransactionCompletedEvent.class);
+   }
+
+   final static class Entry
+   {
+      private final Object listener;
+      private final Pattern pattern;
+      private final Map<Class<?>, List<Method>> notifiers;
+
+      private Entry(Object listener, boolean build)
+      {
+         this(listener, build, null);
+      }
+
+      private Entry(Object listener, boolean build, Pattern pattern)
+      {
+         if (listener == null)
+            throw new IllegalArgumentException("Listener can't be null");
+
+         this.listener = listener;
+         this.pattern = pattern;
+
+         this.notifiers = build ? buildNotifiers(listener.getClass()) : null;
+      }
+
+      // equality is confined to listener
+      public int hashCode()
+      {
+         return listener.hashCode();
+      }
+
+      // equality is confined to listener
+      public boolean equals(Object o)
+      {
+         if (o == this)
+            return true;
+         if (! (o instanceof Entry))
+            return false;
+
+         // Must be the same instance
+         return ((Entry)o).listener == this.listener;
+      }
+
+      private static Map<Class<?>, List<Method>> buildNotifiers(Class<?> clazz)
+      {
+         if (! Modifier.isPublic(clazz.getModifiers()))
+            throw new IllegalArgumentException("Listener must be public! Class:" + clazz.getName());
+
+         if (! clazz.isAnnotationPresent(PojoCacheListener.class))
+            throw new IllegalArgumentException("Not a listener, class did not contain @PojoCacheListener. Class: " + clazz.getName());
+
+
+         Map<Class<?>, List<Method>> notifiers = new HashMap<Class<?>, List<Method>>();
+         for (Method method : clazz.getMethods())
+         {
+            for (Annotation annotation : method.getAnnotations())
+            {
+               Class<? extends Event> event = annotations.get(annotation.annotationType());
+               if (event == null)
+                  continue;
+
+               Class<?>[] types = method.getParameterTypes();
+               if (types.length != 1 || !types[0].isAssignableFrom(event))
+               {
+                  throw new IllegalArgumentException("Listener has invlaid method signature for annotation. " +
+                        "Method: \"" + method.getName() + "\" " +
+                        "Annotation: \"" + annotation.annotationType().getSimpleName() + "\" " +
+                        "Expected Parameter: \"" + event.getSimpleName() + "\"");
+               }
+
+               List<Method> list = notifiers.get(event);
+               if (list == null)
+               {
+                  list = new ArrayList<Method>();
+                  notifiers.put(event, list);
+               }
+
+               list.add(method);
+            }
+         }
+
+         return notifiers;
+      }
+   }
+
+   void add(Object listener)
+   {
+      listeners.add(new Entry(listener, true));
+   }
+
+   // gaurds filteredListeners
+   synchronized void add(Object listener, Pattern pattern)
+   {
+      listeners.add(new Entry(listener, true, pattern));
+      filteredListeners.add(listener);
+      hasFilters = true;
+   }
+
+   // gaurds filteredListeners
+   synchronized void remove(Object listener)
+   {
+      filteredListeners.remove(listener);
+      if (filteredListeners.size() == 0)
+         hasFilters = false;
+      listeners.remove(new Entry(listener, false));
+   }
+
+   boolean hasFilters()
+   {
+      return hasFilters;
+   }
+
+   Set<Object> getListeners()
+   {
+      Set<Object> set = new HashSet<Object>();
+      for (Entry entry : listeners)
+         set.add(entry.listener);
+
+      return Collections.unmodifiableSet(set);
+   }
+
+   Set<Entry> getListenerEntries(Collection<Reference> references)
+   {
+      Set<Entry> set = new HashSet<Entry>();
+      for (Entry entry : listeners)
+      {
+         if (entry.pattern == null)
+         {
+            set.add(entry);
+            continue;
+         }
+
+         for (Reference reference : references)
+         {
+            if (entry.pattern.matcher(reference.getFqn().toString()).matches())
+            {
+               set.add(entry);
+               break;
+            }
+         }
+      }
+
+      return set;
+   }
+
+   boolean isEmpty()
+   {
+      return listeners.size() == 0;
+   }
+
+   void dispatch(Event notification)
+   {
+      for (Entry entry : listeners)
+      {
+         // Prevent dispatch to filtered entries
+         if (entry.pattern == null)
+            dispatch(notification, entry);
+      }
+   }
+
+   void dispatch(Event notification, Set<Entry> listeners)
+   {
+      for (Entry listener : listeners)
+         dispatch(notification, listener);
+   }
+
+   private void dispatch(Event notification, Entry entry)
+   {
+      List<Method> methods = entry.notifiers.get(notification.getClass());
+      if (methods == null)
+         return;
+
+      try
+      {
+         for (Method method : methods)
+            method.invoke(entry.listener, notification);
+      }
+      catch (Exception e)
+      {
+         throw new PojoCacheException(e);
+      }
+   }
+}

Deleted: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/ObjectGraphHandler.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/ObjectGraphHandler.java	2008-07-16 17:30:08 UTC (rev 6310)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/ObjectGraphHandler.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -1,138 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-
-package org.jboss.cache.pojo.impl;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.jboss.cache.CacheException;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.pojo.PojoCacheException;
-
-/**
- * Handle the object graph management.
- *
- * @author Ben Wang
- *         Date: Aug 4, 2005
- * @version $Id$
- */
-class ObjectGraphHandler extends AbstractHandler
-{
-   private PojoCacheImpl cache;
-   private InternalHelper internal_;
-   private final static Log log = LogFactory.getLog(ObjectGraphHandler.class);
-
-   public ObjectGraphHandler(PojoCacheImpl cache, InternalHelper internal)
-   {
-      this.cache = cache;
-      internal_ = internal;
-   }
-
-   protected Fqn<?> getFqn(Object obj)
-   {
-      return null;
-   }
-
-   protected boolean handles(Class<?> clazz)
-   {
-      return false;
-   }
-
-   @Override
-   protected Object get(Fqn<?> fqn, Class<?> clazz, PojoInstance pojoInstance) throws CacheException
-   {
-      // Note this is actually the aliasFqn, not the real fqn!
-      Object obj;
-
-      obj = cache.find(fqn);
-      if (obj == null)
-         throw new PojoCacheException("ObjectGraphHandler.get(): null object from internal ref node." +
-                                      " Internal ref node: " + fqn);
-
-      return obj; // No need to set the instance under fqn. It is located in refFqn anyway.
-   }
-
-   @Override
-   protected void put(Fqn<?> fqn, Fqn<?> referencingFqn, Object obj) throws CacheException
-   {
-      setupRefCounting(fqn, referencingFqn);
-   }
-
-   boolean isMultipleReferenced(Fqn<?> internalFqn)
-   {
-      // Note this is actually the aliasFqn, not the real fqn!
-      PojoInstance pojoInstance = null;
-      try
-      {
-         pojoInstance = internal_.getPojoInstance(internalFqn);
-      }
-      catch (CacheException e)
-      {
-         throw new PojoCacheException("Exception in isMultipleReferenced", e);
-      }
-      // check if this is a refernce
-      return InternalHelper.isMultipleReferenced(pojoInstance);
-
-   }
-
-   @Override
-   protected Object remove(Fqn<?> fqn, Fqn<?> referencingFqn, Object pojo)
-         throws CacheException
-   {
-      if (log.isDebugEnabled())
-      {
-         log.debug("remove(): removing object fqn: " + referencingFqn
-                   + " Will just de-reference it.");
-      }
-      removeFromReference(fqn, referencingFqn);
-
-      return null;
-   }
-
-   /**
-    * Remove the object from the the reference fqn, meaning just decrement the ref counter.
-    */
-   private void removeFromReference(Fqn<?> originalFqn, Fqn<?> referencingFqn) throws CacheException
-   {
-      synchronized (originalFqn)
-      {  // we lock the internal fqn here so no one else has access.
-         // Decrement ref counting on the internal node
-         if (decrementRefCount(originalFqn, referencingFqn) == PojoInstance.INITIAL_COUNTER_VALUE)
-         {
-            // No one is referring it so it is safe to remove
-            // TODO we should make sure the parent nodes are also removed they are empty as well.
-            cache.detach(originalFqn);
-         }
-      }
-   }
-
-   /**
-    * 1. increment reference counter
-    * 2. put in refFqn so we can get it.
-    *
-    * @param fqn    The original fqn node
-    * @param refFqn The new internal fqn node
-    */
-   private void setupRefCounting(Fqn<?> fqn, Fqn<?> referencingFqn) throws CacheException
-   {
-      synchronized (fqn)
-      {
-         // increment the reference counting
-         incrementRefCount(fqn, referencingFqn);
-      }
-   }
-
-   private int incrementRefCount(Fqn<?> originalFqn, Fqn<?> referencingFqn) throws CacheException
-   {
-      return internal_.incrementRefCount(originalFqn, referencingFqn);
-   }
-
-   private int decrementRefCount(Fqn<?> originalFqn, Fqn<?> referencingFqn) throws CacheException
-   {
-      return internal_.decrementRefCount(originalFqn, referencingFqn);
-   }
-}

Copied: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/ObjectGraphHandler.java (from rev 6551, pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/ObjectGraphHandler.java)
===================================================================
--- pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/ObjectGraphHandler.java	                        (rev 0)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/ObjectGraphHandler.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -0,0 +1,132 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+package org.jboss.cache.pojo.impl;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.CacheException;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.pojo.PojoCacheException;
+import org.jboss.cache.pojo.Reference;
+
+/**
+ * Handle the object graph management.
+ *
+ * @author Ben Wang
+ *         Date: Aug 4, 2005
+ * @version $Id$
+ */
+class ObjectGraphHandler extends AbstractHandler
+{
+   private PojoCacheImpl cache;
+   private InternalHelper internal_;
+   private final static Log log = LogFactory.getLog(ObjectGraphHandler.class);
+
+   public ObjectGraphHandler(PojoCacheImpl cache, InternalHelper internal)
+   {
+      this.cache = cache;
+      internal_ = internal;
+   }
+
+   protected Fqn<?> getFqn(Object obj)
+   {
+      return null;
+   }
+
+   protected boolean handles(Class<?> clazz)
+   {
+      return false;
+   }
+
+   @Override
+   protected Object get(Fqn<?> fqn, Class<?> clazz, PojoInstance pojoInstance) throws CacheException
+   {
+      // Note this is actually the aliasFqn, not the real fqn!
+      Object obj;
+
+      obj = cache.find(fqn);
+      if (obj == null)
+         throw new PojoCacheException("ObjectGraphHandler.get(): null object from internal ref node." +
+                                      " Internal ref node: " + fqn);
+
+      return obj; // No need to set the instance under fqn. It is located in refFqn anyway.
+   }
+
+   @Override
+   protected void put(Fqn<?> fqn, Reference reference, Object obj) throws CacheException
+   {
+      setupRefCounting(fqn, reference);
+   }
+
+   boolean isMultipleReferenced(Fqn<?> internalFqn)
+   {
+      // Note this is actually the aliasFqn, not the real fqn!
+      PojoInstance pojoInstance = null;
+      try
+      {
+         pojoInstance = internal_.getPojoInstance(internalFqn);
+      }
+      catch (CacheException e)
+      {
+         throw new PojoCacheException("Exception in isMultipleReferenced", e);
+      }
+      // check if this is a refernce
+      return InternalHelper.isMultipleReferenced(pojoInstance);
+
+   }
+
+   @Override
+   protected Object remove(Fqn<?> fqn, Reference reference, Object pojo)
+         throws CacheException
+   {
+      if (log.isDebugEnabled())
+      {
+         log.debug("remove(): removing object fqn: " + reference
+                   + " Will just de-reference it.");
+      }
+      removeFromReference(fqn, reference);
+
+      return null;
+   }
+
+   /**
+    * Remove the object from the the reference fqn, meaning just decrement the ref counter.
+    */
+   private void removeFromReference(Fqn<?> originalFqn, Reference reference) throws CacheException
+   {
+      if (decrementRefCount(originalFqn, reference) == PojoInstance.INITIAL_COUNTER_VALUE)
+      {
+         // No one is referring it so it is safe to remove
+         // TODO we should make sure the parent nodes are also removed they are empty as well.
+         cache.detach(originalFqn);
+      }
+   }
+
+   /**
+    * 1. increment reference counter
+    * 2. put in refFqn so we can get it.
+    *
+    * @param fqn    The original fqn node
+    * @param refFqn The new internal fqn node
+    */
+   private void setupRefCounting(Fqn<?> fqn, Reference reference) throws CacheException
+   {
+      // increment the reference counting
+      incrementRefCount(fqn, reference);
+   }
+
+   private int incrementRefCount(Fqn<?> originalFqn, Reference reference) throws CacheException
+   {
+      return internal_.incrementRefCount(originalFqn, reference);
+   }
+
+   private int decrementRefCount(Fqn<?> originalFqn, Reference reference) throws CacheException
+   {
+      return internal_.decrementRefCount(originalFqn, reference);
+   }
+}

Deleted: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/PojoCacheDelegate.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheDelegate.java	2008-07-16 17:30:08 UTC (rev 6310)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/PojoCacheDelegate.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -1,349 +0,0 @@
-/*
- * JBoss, the OpenSource J2EE webOS
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package org.jboss.cache.pojo.impl;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.jboss.aop.Advised;
-import org.jboss.aop.Advisor;
-import org.jboss.aop.InstanceAdvisor;
-import org.jboss.aop.advice.Interceptor;
-import org.jboss.aop.proxy.ClassProxy;
-import org.jboss.cache.Cache;
-import org.jboss.cache.CacheException;
-import org.jboss.cache.CacheSPI;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.Node;
-import org.jboss.cache.Region;
-import org.jboss.cache.pojo.PojoCacheException;
-import org.jboss.cache.pojo.collection.CollectionInterceptorUtil;
-import org.jboss.cache.pojo.interceptors.dynamic.AbstractCollectionInterceptor;
-import org.jboss.cache.pojo.interceptors.dynamic.BaseInterceptor;
-import org.jboss.cache.pojo.memory.FieldPersistentReference;
-import org.jboss.cache.pojo.util.AopUtil;
-
-import java.lang.reflect.Field;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Delegate class for PojoCache, the real implementation code happens here.
- *
- * @author Ben Wang
- */
-public class PojoCacheDelegate
-{
-   private PojoCacheImpl pojoCache;
-   private Cache<Object, Object> cache;
-   private final static Log log = LogFactory.getLog(PojoCacheDelegate.class);
-   private InternalHelper internal_;
-   private AdvisedPojoHandler advisedHandler_;
-   private ObjectGraphHandler graphHandler_;
-   private CollectionClassHandler collectionHandler_;
-   private ArrayHandler arrayHandler;
-   private SerializableObjectHandler serializableHandler_;
-   // Use ThreadLocal to hold a boolean isBulkRemove
-   private PojoUtil util_ = new PojoUtil();
-
-   public PojoCacheDelegate(PojoCacheImpl cache)
-   {
-      pojoCache = cache;
-      this.cache = pojoCache.getCache();
-      internal_ = new InternalHelper(cache);
-      graphHandler_ = new ObjectGraphHandler(pojoCache, internal_);
-      collectionHandler_ = new CollectionClassHandler(pojoCache, internal_);
-      serializableHandler_ = new SerializableObjectHandler(pojoCache, internal_);
-      advisedHandler_ = new AdvisedPojoHandler(pojoCache, internal_, util_);
-      arrayHandler = new ArrayHandler(pojoCache);
-   }
-
-   public Object getObject(Fqn fqn, String field, Object source) throws CacheException
-   {
-      // TODO Must we really to couple with BR? JBCACHE-669
-      Object pojo = internal_.getPojo(fqn, field);
-      if (pojo != null)
-      {
-         // we already have an advised instance
-         if (log.isDebugEnabled())
-         {
-            log.debug("getObject(): id: " + fqn + " retrieved from existing instance directly. ");
-         }
-         return pojo;
-      }
-
-      // OK. So we are here meaning that this is a failover or passivation since the transient
-      // pojo instance is not around. Let's also make sure the right classloader is used
-      // as well.
-      ClassLoader prevCL = Thread.currentThread().getContextClassLoader();
-      try
-      {
-         Region region = cache.getRegion(fqn, false);
-         if (region != null && region.getClassLoader() != null)
-            Thread.currentThread().setContextClassLoader(region.getClassLoader());
-
-         return getObjectInternal(fqn, field, source);
-      }
-      finally
-      {
-         Thread.currentThread().setContextClassLoader(prevCL);
-      }
-   }
-
-   /**
-    * Note that caller of this method will take care of synchronization within the <code>fqn</code> sub-tree.
-    */
-   public Object putObject(Fqn fqn, Object obj, String field, Object source) throws CacheException
-   {
-      internal_.lockPojo(fqn);
-
-      // Skip some un-necessary update if obj is the same class as the old one
-      Object oldValue = internal_.getPojo(fqn, field);
-      boolean allowArray = source instanceof ArrayInterceptable;
-      if (oldValue == obj && skipDuplicateAttach(obj, allowArray))
-      {
-         if (log.isDebugEnabled())
-         {
-            log.debug("putObject(): id: " + fqn + " pojo is already in the cache. Return right away.");
-         }
-         return obj;
-      }
-
-      // remove old value before overwriting it. This is necessary to detach any interceptor.
-      // TODO Or can we simply walk thru that somewhere? Well, there is also implication of Collection though
-      pojoCache.detach(fqn, field, source);
-
-      if (obj == null)
-         return oldValue;// we are done
-
-      AbstractHandler handler = getHandler(obj.getClass(), allowArray);
-      Fqn<?> internalFqn = handler.getFqn(obj);
-
-      if (internalFqn != null)
-      {
-         graphHandler_.put(internalFqn, fqn, obj);
-      }
-      else
-      {
-         internalFqn = createInternalFqn(fqn, obj);
-         if (log.isDebugEnabled())
-            log.debug("attach(): id: " + fqn + " will store the pojo in the internal area: " + internalFqn);
-
-         handler.put(internalFqn, fqn, obj);
-
-         // Used by notification sub-system
-         cache.put(internalFqn, InternalConstant.POJOCACHE_STATUS, "ATTACHED");
-      }
-
-      setPojoReference(fqn, obj, field, internalFqn);
-
-      return oldValue;
-   }
-
-   private boolean skipDuplicateAttach(Object obj, boolean allowArray)
-   {
-      return obj == null || getHandler(obj.getClass(), allowArray) != serializableHandler_;
-   }
-
-   private AbstractHandler getHandler(Class<?> clazz, boolean allowArray)
-   {
-      if (advisedHandler_.handles(clazz))
-         return advisedHandler_;
-
-      if (collectionHandler_.handles(clazz))
-         return collectionHandler_;
-
-      if (allowArray && arrayHandler.handles(clazz))
-         return arrayHandler;
-
-      if (serializableHandler_.handles(clazz))
-         return serializableHandler_;
-
-      throw new CacheException("Can not manage object. It must be either instrumented, a collection, an array, or Serializable: "
-            + clazz.getName());
-   }
-
-
-   private Fqn createInternalFqn(Fqn fqn, Object obj) throws CacheException
-   {
-      // Create an internal Fqn name
-      return AopUtil.createInternalFqn(fqn, cache);
-   }
-
-   private Fqn setPojoReference(Fqn fqn, Object obj, String field, Fqn internalFqn) throws CacheException
-   {
-      // Create PojoReference
-      CachedType type = pojoCache.getCachedType(obj.getClass());
-      PojoReference pojoReference = new PojoReference();
-      pojoReference.setPojoClass(type.getType());
-
-      // store PojoReference
-      pojoReference.setFqn(internalFqn);
-      internal_.putPojoReference(fqn, pojoReference, field);
-      if (log.isDebugEnabled())
-      {
-         log.debug("put(): inserting PojoReference with id: " + fqn);
-      }
-      // store obj in the internal fqn
-      return internalFqn;
-   }
-
-   private void createChildNodeFirstWithoutLocking(Fqn internalFqn)
-   {
-      int size = internalFqn.size();
-      Fqn f = internalFqn.getSubFqn(0, size - 1);
-      Fqn child = internalFqn.getSubFqn(size - 1, size);
-
-      Node base = cache.getRoot().getChild(f);
-      if (base == null)
-      {
-         log.debug("The node retrieved is null from fqn: " + f);
-         return;
-      }
-      base.addChild(child);
-   }
-
-   /**
-    * Note that caller of this method will take care of synchronization within the <code>fqn</code> sub-tree.
-    *
-    * @param fqn
-    * @return detached object
-    * @throws CacheException
-    */
-   public Object removeObject(Fqn fqn, String field, Object source) throws CacheException
-   {
-      internal_.lockPojo(fqn);
-
-      // the class attribute is implicitly stored as an immutable read-only attribute
-      PojoReference pojoReference = internal_.getPojoReference(fqn, field);
-      if (pojoReference == null)
-      {
-         //  clazz and pojoReference can be not null if this node is the replicated brother node.
-         if (log.isTraceEnabled())
-         {
-            log.trace("removeObject(): clazz is null. id: " + fqn + " No need to remove.");
-         }
-         return null;
-      }
-
-      Fqn<?> internalFqn = pojoReference.getFqn();
-
-      if (log.isDebugEnabled())
-      {
-         log.debug("removeObject(): removing object from id: " + fqn
-                   + " with the corresponding internal id: " + internalFqn);
-      }
-
-      Object result = pojoCache.find(internalFqn);
-      if (result == null)
-         return null;
-
-      if (graphHandler_.isMultipleReferenced(internalFqn))
-      {
-         graphHandler_.remove(internalFqn, fqn, result);
-      }
-      else
-      {
-         cache.put(internalFqn, InternalConstant.POJOCACHE_STATUS, "DETACHING");
-         boolean allowArray = source instanceof ArrayInterceptable;
-         result = getHandler(result.getClass(), allowArray).remove(internalFqn, fqn, result);
-      }
-
-      internal_.cleanUp(fqn, field);
-      return result;
-   }
-
-   public Map findObjects(Fqn fqn) throws CacheException
-   {
-
-      // Traverse from fqn to do getObject, if it return a pojo we then stop.
-      Map map = new HashMap();
-      Object pojo = getObject(fqn, null, null);
-      if (pojo != null)
-      {
-         map.put(fqn, pojo);// we are done!
-         return map;
-      }
-
-      findChildObjects(fqn, map);
-      if (log.isDebugEnabled())
-      {
-         log.debug("_findObjects(): id: " + fqn + " size of pojos found: " + map.size());
-      }
-      return map;
-   }
-
-   private Object getObjectInternal(Fqn<?> fqn, String field, Object source) throws CacheException
-   {
-      Fqn<?> internalFqn = fqn;
-      PojoReference pojoReference = internal_.getPojoReference(fqn, field);
-      if (pojoReference != null)
-      {
-         internalFqn = pojoReference.getFqn();
-      }
-      else if (field != null)
-      {
-         return null;
-      }
-
-      if (log.isDebugEnabled())
-         log.debug("getObject(): id: " + fqn + " with a corresponding internal id: " + internalFqn);
-
-      /**
-       * Reconstruct the managed POJO
-       */
-      Object obj;
-
-      PojoInstance pojoInstance = internal_.getPojoInstance(internalFqn);
-
-      if (pojoInstance == null)
-         return null;
-         //throw new PojoCacheException("PojoCacheDelegate.getObjectInternal(): null PojoInstance for fqn: " + internalFqn);
-
-      Class<?> clazz = pojoInstance.getPojoClass();
-      boolean allowArray = source instanceof ArrayInterceptable;
-      obj = getHandler(clazz, allowArray).get(internalFqn, clazz, pojoInstance);
-
-      InternalHelper.setPojo(pojoInstance, obj);
-      return obj;
-   }
-
-   private void findChildObjects(Fqn fqn, Map map) throws CacheException
-   {
-      // We need to traverse then
-      Node root = cache.getRoot();
-      Node current = root.getChild(fqn);
-
-      if (current == null) return;
-
-      Collection<Node> col = current.getChildren();
-      if (col == null) return;
-      for (Node n : col)
-      {
-         Fqn newFqn = n.getFqn();
-         if (InternalHelper.isInternalNode(newFqn)) continue;// skip
-
-         Object pojo = getObject(newFqn, null, null);
-         if (pojo != null)
-         {
-            map.put(newFqn, pojo);
-         }
-         else
-         {
-            findChildObjects(newFqn, map);
-         }
-      }
-   }
-
-   public boolean exists(Fqn<?> id)
-   {
-      return internal_.getPojoReference(id, null) != null || internal_.getPojoInstance(id) != null;
-   }
-}

Copied: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/PojoCacheDelegate.java (from rev 6551, pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheDelegate.java)
===================================================================
--- pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/PojoCacheDelegate.java	                        (rev 0)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/PojoCacheDelegate.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -0,0 +1,371 @@
+/*
+ * JBoss, the OpenSource J2EE webOS
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jboss.cache.pojo.impl;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.aop.Advised;
+import org.jboss.aop.Advisor;
+import org.jboss.aop.InstanceAdvisor;
+import org.jboss.aop.advice.Interceptor;
+import org.jboss.aop.proxy.ClassProxy;
+import org.jboss.cache.Cache;
+import org.jboss.cache.CacheException;
+import org.jboss.cache.CacheSPI;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.Node;
+import org.jboss.cache.Region;
+import org.jboss.cache.pojo.PojoCacheException;
+import org.jboss.cache.pojo.Reference;
+import org.jboss.cache.pojo.collection.CollectionInterceptorUtil;
+import org.jboss.cache.pojo.interceptors.dynamic.AbstractCollectionInterceptor;
+import org.jboss.cache.pojo.interceptors.dynamic.BaseInterceptor;
+import org.jboss.cache.pojo.memory.FieldPersistentReference;
+import org.jboss.cache.pojo.util.AopUtil;
+
+import java.lang.reflect.Field;
+import java.util.*;
+
+/**
+ * Delegate class for PojoCache, the real implementation code happens here.
+ *
+ * @author Ben Wang
+ */
+public class PojoCacheDelegate
+{
+   private PojoCacheImpl pojoCache;
+   private Cache<Object, Object> cache;
+   private final static Log log = LogFactory.getLog(PojoCacheDelegate.class);
+   private InternalHelper internal_;
+   private AdvisedPojoHandler advisedHandler_;
+   private ObjectGraphHandler graphHandler_;
+   private CollectionClassHandler collectionHandler_;
+   private ArrayHandler arrayHandler;
+   private SerializableObjectHandler serializableHandler_;
+   // Use ThreadLocal to hold a boolean isBulkRemove
+   private PojoUtil util_ = new PojoUtil();
+
+   public PojoCacheDelegate(PojoCacheImpl cache)
+   {
+      pojoCache = cache;
+      this.cache = pojoCache.getCache();
+      internal_ = new InternalHelper(cache);
+      graphHandler_ = new ObjectGraphHandler(pojoCache, internal_);
+      collectionHandler_ = new CollectionClassHandler(pojoCache, internal_);
+      serializableHandler_ = new SerializableObjectHandler(pojoCache, internal_);
+      advisedHandler_ = new AdvisedPojoHandler(pojoCache, internal_, util_);
+      arrayHandler = new ArrayHandler(pojoCache);
+   }
+
+   public Object getObject(Fqn fqn, String field, Object source) throws CacheException
+   {
+      // TODO Must we really to couple with BR? JBCACHE-669
+      Object pojo = internal_.getPojo(fqn, field);
+      if (pojo != null)
+      {
+         // we already have an advised instance
+         if (log.isDebugEnabled())
+         {
+            log.debug("getObject(): id: " + fqn + " retrieved from existing instance directly. ");
+         }
+         return pojo;
+      }
+
+      // OK. So we are here meaning that this is a failover or passivation since the transient
+      // pojo instance is not around. Let's also make sure the right classloader is used
+      // as well.
+      ClassLoader prevCL = Thread.currentThread().getContextClassLoader();
+      try
+      {
+         Region region = cache.getRegion(fqn, false);
+         if (region != null && region.getClassLoader() != null)
+            Thread.currentThread().setContextClassLoader(region.getClassLoader());
+
+         return getObjectInternal(fqn, field, source);
+      }
+      finally
+      {
+         Thread.currentThread().setContextClassLoader(prevCL);
+      }
+   }
+
+   /**
+    * Note that caller of this method will take care of synchronization within the <code>fqn</code> sub-tree.
+    */
+   public Object putObject(Fqn fqn, Object obj, String field, Object source) throws CacheException
+   {
+      internal_.lockPojo(fqn);
+
+      // Skip some un-necessary update if obj is the same class as the old one
+      Object oldValue = internal_.getPojo(fqn, field);
+      boolean allowArray = source instanceof ArrayInterceptable;
+      if (oldValue == obj && skipDuplicateAttach(obj, allowArray))
+      {
+         if (log.isDebugEnabled())
+         {
+            log.debug("putObject(): id: " + fqn + " pojo is already in the cache. Return right away.");
+         }
+         return obj;
+      }
+
+      // remove old value before overwriting it. This is necessary to detach any interceptor.
+      // TODO Or can we simply walk thru that somewhere? Well, there is also implication of Collection though
+      pojoCache.detach(fqn, field, source);
+
+      if (obj == null)
+         return oldValue;// we are done
+
+      AbstractHandler handler = getHandler(obj.getClass(), allowArray);
+      Fqn<?> internalFqn = handler.getFqn(obj);
+
+      Reference reference = new ReferenceImpl(fqn, field);
+      if (internalFqn != null)
+      {
+         // Lock the internal fqn, before the ref count is checked
+         internal_.lockPojo(internalFqn);
+         graphHandler_.put(internalFqn, reference , obj);
+      }
+      else
+      {
+         internalFqn = createInternalFqn(fqn, obj);
+         if (log.isDebugEnabled())
+            log.debug("attach(): id: " + fqn + " will store the pojo in the internal area: " + internalFqn);
+
+         handler.put(internalFqn, reference, obj);
+
+         // Used by notification sub-system
+         cache.put(internalFqn, InternalConstant.POJOCACHE_STATUS, "ATTACHED");
+      }
+
+      setPojoReference(fqn, obj, field, internalFqn);
+
+      return oldValue;
+   }
+
+   private boolean skipDuplicateAttach(Object obj, boolean allowArray)
+   {
+      return obj == null || getHandler(obj.getClass(), allowArray) != serializableHandler_;
+   }
+
+   private AbstractHandler getHandler(Class<?> clazz, boolean allowArray)
+   {
+      if (advisedHandler_.handles(clazz))
+         return advisedHandler_;
+
+      if (collectionHandler_.handles(clazz))
+         return collectionHandler_;
+
+      if (allowArray && arrayHandler.handles(clazz))
+         return arrayHandler;
+
+      if (serializableHandler_.handles(clazz))
+         return serializableHandler_;
+
+      throw new CacheException("Can not manage object. It must be either instrumented, a collection, an array, or Serializable: "
+            + clazz.getName());
+   }
+
+
+   private Fqn createInternalFqn(Fqn fqn, Object obj) throws CacheException
+   {
+      // Create an internal Fqn name
+      return AopUtil.createInternalFqn(fqn, cache);
+   }
+
+   private Fqn setPojoReference(Fqn fqn, Object obj, String field, Fqn internalFqn) throws CacheException
+   {
+      // Create PojoReference
+      CachedType type = pojoCache.getCachedType(obj.getClass());
+      PojoReference pojoReference = new PojoReference();
+      pojoReference.setPojoClass(type.getType());
+
+      // store PojoReference
+      pojoReference.setFqn(internalFqn);
+      internal_.putPojoReference(fqn, pojoReference, field);
+      if (log.isDebugEnabled())
+      {
+         log.debug("put(): inserting PojoReference with id: " + fqn);
+      }
+      // store obj in the internal fqn
+      return internalFqn;
+   }
+
+   private void createChildNodeFirstWithoutLocking(Fqn internalFqn)
+   {
+      int size = internalFqn.size();
+      Fqn f = internalFqn.getSubFqn(0, size - 1);
+      Fqn child = internalFqn.getSubFqn(size - 1, size);
+
+      Node base = cache.getRoot().getChild(f);
+      if (base == null)
+      {
+         log.debug("The node retrieved is null from fqn: " + f);
+         return;
+      }
+      base.addChild(child);
+   }
+
+   /**
+    * Note that caller of this method will take care of synchronization within the <code>fqn</code> sub-tree.
+    *
+    * @param fqn
+    * @return detached object
+    * @throws CacheException
+    */
+   public Object removeObject(Fqn fqn, String field, Object source) throws CacheException
+   {
+      internal_.lockPojo(fqn);
+
+      // the class attribute is implicitly stored as an immutable read-only attribute
+      PojoReference pojoReference = internal_.getPojoReference(fqn, field);
+      if (pojoReference == null)
+      {
+         //  clazz and pojoReference can be not null if this node is the replicated brother node.
+         if (log.isTraceEnabled())
+         {
+            log.trace("removeObject(): clazz is null. id: " + fqn + " No need to remove.");
+         }
+         return null;
+      }
+
+      Fqn<?> internalFqn = pojoReference.getFqn();
+
+
+
+      if (log.isDebugEnabled())
+      {
+         log.debug("removeObject(): removing object from id: " + fqn
+                   + " with the corresponding internal id: " + internalFqn);
+      }
+
+      Object result = pojoCache.find(internalFqn);
+      if (result == null)
+         return null;
+
+      // Lock the internal fqn, before the ref count is checked
+      internal_.lockPojo(internalFqn);
+
+      Reference reference = new ReferenceImpl(fqn, field);
+      if (graphHandler_.isMultipleReferenced(internalFqn))
+      {
+         graphHandler_.remove(internalFqn, reference, result);
+      }
+      else
+      {
+         cache.put(internalFqn, InternalConstant.POJOCACHE_STATUS, "DETACHING");
+         boolean allowArray = source instanceof ArrayInterceptable;
+         result = getHandler(result.getClass(), allowArray).remove(internalFqn, reference, result);
+      }
+
+      internal_.cleanUp(fqn, field);
+      return result;
+   }
+
+   public Map findObjects(Fqn fqn) throws CacheException
+   {
+
+      // Traverse from fqn to do getObject, if it return a pojo we then stop.
+      Map map = new HashMap();
+      Object pojo = getObject(fqn, null, null);
+      if (pojo != null)
+      {
+         map.put(fqn, pojo);// we are done!
+         return map;
+      }
+
+      findChildObjects(fqn, map);
+      if (log.isDebugEnabled())
+      {
+         log.debug("_findObjects(): id: " + fqn + " size of pojos found: " + map.size());
+      }
+      return map;
+   }
+
+   private Object getObjectInternal(Fqn<?> fqn, String field, Object source) throws CacheException
+   {
+      Fqn<?> internalFqn = fqn;
+      PojoReference pojoReference = internal_.getPojoReference(fqn, field);
+      if (pojoReference != null)
+      {
+         internalFqn = pojoReference.getFqn();
+      }
+      else if (field != null)
+      {
+         return null;
+      }
+
+      if (log.isDebugEnabled())
+         log.debug("getObject(): id: " + fqn + " with a corresponding internal id: " + internalFqn);
+
+      /**
+       * Reconstruct the managed POJO
+       */
+      Object obj;
+
+      PojoInstance pojoInstance = internal_.getPojoInstance(internalFqn);
+
+      if (pojoInstance == null)
+         return null;
+         //throw new PojoCacheException("PojoCacheDelegate.getObjectInternal(): null PojoInstance for fqn: " + internalFqn);
+
+      Class<?> clazz = pojoInstance.getPojoClass();
+      boolean allowArray = source instanceof ArrayInterceptable;
+      obj = getHandler(clazz, allowArray).get(internalFqn, clazz, pojoInstance);
+
+      InternalHelper.setPojo(pojoInstance, obj);
+      return obj;
+   }
+
+   private void findChildObjects(Fqn fqn, Map map) throws CacheException
+   {
+      // We need to traverse then
+      Node root = cache.getRoot();
+      Node current = root.getChild(fqn);
+
+      if (current == null) return;
+
+      Collection<Node> col = current.getChildren();
+      if (col == null) return;
+      for (Node n : col)
+      {
+         Fqn newFqn = n.getFqn();
+         if (InternalHelper.isInternalNode(newFqn)) continue;// skip
+
+         Object pojo = getObject(newFqn, null, null);
+         if (pojo != null)
+         {
+            map.put(newFqn, pojo);
+         }
+         else
+         {
+            findChildObjects(newFqn, map);
+         }
+      }
+   }
+
+   public boolean exists(Fqn<?> id)
+   {
+      return internal_.getPojoReference(id, null) != null || internal_.getPojoInstance(id) != null;
+   }
+
+   public Fqn<?> getInternalFqn(Object object)
+   {
+      AbstractHandler handler = getHandler(object.getClass(), true);
+      Fqn<?> internalFqn = handler.getFqn(object);
+      return internalFqn;
+   }
+
+   public Collection<Reference> getReferences(Object object)
+   {
+      Fqn<?> fqn = getInternalFqn(object);
+      if (fqn == null)
+         return Collections.emptyList();
+
+      PojoInstance pojoInstance = internal_.getPojoInstance(fqn);
+      return pojoInstance.getReferences();
+   }
+}

Deleted: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/PojoCacheImpl.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheImpl.java	2008-07-16 17:30:08 UTC (rev 6310)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/PojoCacheImpl.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -1,411 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-
-package org.jboss.cache.pojo.impl;
-
-import java.util.Collection;
-import java.util.Map;
-import java.util.WeakHashMap;
-import java.util.regex.Pattern;
-
-import javax.transaction.Status;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.jboss.cache.Cache;
-import org.jboss.cache.CacheException;
-import org.jboss.cache.CacheSPI;
-import org.jboss.cache.DefaultCacheFactory;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.Version;
-import org.jboss.cache.config.Configuration;
-import org.jboss.cache.factories.XmlConfigurationParser;
-import org.jboss.cache.pojo.PojoCache;
-import org.jboss.cache.pojo.PojoCacheException;
-import org.jboss.cache.pojo.PojoCacheThreadContext;
-import org.jboss.cache.pojo.interceptors.PojoTxSynchronizationHandler;
-import org.jboss.cache.transaction.BatchModeTransactionManager;
-
-/**
- * Implementation class for PojoCache interface
- *
- * @author Ben Wang
- * @version $Id$
- */
-public class PojoCacheImpl implements PojoCache
-{
-   private CacheSPI<Object, Object> cache = null;
-   protected final Log log_ = LogFactory.getLog(PojoCacheImpl.this.getClass());
-   private PojoCacheDelegate delegate_;
-   // Class -> CachedType
-   // use WeakHashMap to allow class reloading
-   private Map cachedTypes_ = new WeakHashMap();
-   private boolean hasCreate_ = false;
-   private CacheListenerAdaptor listenerAdaptor = new CacheListenerAdaptor(this);
-   private PojoCacheThreadContext threadContext = new PojoCacheThreadContextImpl();
-
-   public PojoCacheImpl(String configStr, boolean toStart)
-   {
-      try
-      {
-         //         cache_ = new PojoTreeCache();
-         //         cache_.setConfiguration(new XmlConfigurationParser().parseFile(configStr));
-
-         XmlConfigurationParser parser = new XmlConfigurationParser();
-         Configuration expected = parser.parseFile(configStr);
-
-         init(expected, toStart);
-      }
-      catch (Exception e)
-      {
-         throw new PojoCacheException("Failed to start " + configStr, e);
-      }
-   }
-
-   public PojoCacheImpl(Configuration config, boolean toStart)
-   {
-      init(config, toStart);
-   }
-
-   private void init(Configuration config, boolean toStart)
-   {
-      try
-      {
-         cache = (CacheSPI<Object, Object>) DefaultCacheFactory.getInstance().createCache(config, toStart);
-      }
-      catch (Exception e)
-      {
-         throw new PojoCacheException("init " + config + " failed", e);
-      }
-
-      delegate_ = new PojoCacheDelegate(this);
-   }
-
-   public CacheSPI<Object, Object> getCacheSPI()
-   {
-      return cache;
-   }
-
-   public Object attach(String id, Object pojo) throws PojoCacheException
-   {
-      return attach(Fqn.fromString(id), pojo);
-   }
-
-   public Object attach(Fqn<?> id, Object pojo) throws PojoCacheException
-   {
-      return attach(id, pojo, null, null);
-   }
-
-   public Object attach(Fqn<?> id, Object pojo, String field, Object source) throws PojoCacheException
-   {
-      TransactionManager tm = getTransactionManager();
-      boolean createdTransaction = setupTransaction(tm);
-      try
-      {
-         Object obj = delegate_.putObject(id, pojo, field, source);
-         return obj;
-      }
-      catch (Throwable t)
-      {
-         setRollbackOnly(tm);
-         throw new PojoCacheException("attach failed " + id, t);
-      }
-      finally
-      {
-         if (createdTransaction)
-            endTransaction(tm, id);
-      }
-   }
-
-   public Object detach(Fqn<?> id, String field, Object source) throws PojoCacheException
-   {
-      TransactionManager tm = getTransactionManager();
-      boolean createdTransaction = setupTransaction(tm);
-      try
-      {
-         Object obj = delegate_.removeObject(id, field, source);
-         return obj;
-      }
-      catch (Throwable t)
-      {
-         setRollbackOnly(tm);
-         throw new PojoCacheException("detach failed " + id, t);
-      }
-      finally
-      {
-         if (createdTransaction)
-            endTransaction(tm, id);
-      }
-   }
-
-   private void endTransaction(TransactionManager tm, Fqn<?> id)
-   {
-      try
-      {
-         switch (tm.getStatus())
-         {
-            case Status.STATUS_PREPARING:
-            case Status.STATUS_PREPARED:
-            case Status.STATUS_ACTIVE:
-               tm.commit();
-               break;
-            case Status.STATUS_MARKED_ROLLBACK:
-               tm.rollback();
-               break;
-         }
-      }
-      catch (Throwable t)
-      {
-         if (log_.isWarnEnabled())
-            log_.warn("Could not end transaction for operation on: " + id, t);
-      }
-   }
-
-   private void setRollbackOnly(TransactionManager tm)
-   {
-      try
-      {
-         if (tm.getStatus() != Status.STATUS_MARKED_ROLLBACK)
-            tm.setRollbackOnly();
-      }
-      catch (Throwable t)
-      {
-         if (log_.isWarnEnabled())
-            log_.warn("Could not rollback transaction!", t);
-      }
-   }
-
-   private boolean setupTransaction(TransactionManager tm)
-   {
-      boolean created = false;
-      try
-      {
-         Transaction transaction = tm.getTransaction();
-         if (transaction == null)
-         {
-            tm.begin();
-            transaction = tm.getTransaction();
-            created = true;
-         }
-
-         transaction.registerSynchronization(PojoTxSynchronizationHandler.create());
-      }
-      catch (Exception e)
-      {
-         throw new PojoCacheException("Error creating transaction", e);
-      }
-
-      return created;
-   }
-
-   private TransactionManager getTransactionManager()
-   {
-      TransactionManager tm = cache.getConfiguration().getRuntimeConfig().getTransactionManager();
-      if (tm == null)
-         tm = BatchModeTransactionManager.getInstance();
-
-      return tm;
-   }
-
-   public Object detach(String id) throws PojoCacheException
-   {
-      return detach(Fqn.fromString(id));
-   }
-
-
-
-   public Object detach(Fqn<?> id) throws PojoCacheException
-   {
-      return detach(id, null, null);
-   }
-
-   public String getPojoID(Object pojo)
-   {
-      throw new PojoCacheException("getPojoID not yet implemented");
-   }
-
-   public boolean exists(Fqn<?> id)
-   {
-      return delegate_.exists(id);
-   }
-
-   public Object find(String id) throws PojoCacheException
-   {
-      return find(Fqn.fromString(id));
-   }
-
-   public Object find(Fqn<?> id) throws PojoCacheException
-   {
-      try
-      {
-         return find(id, null, null);
-      }
-      catch (CacheException e)
-      {
-         throw new PojoCacheException("find " + id + " failed ", e);
-      }
-   }
-
-   public Object find(Fqn<?> id, String field, Object source) throws CacheException
-   {
-      return delegate_.getObject(id, field, source);
-   }
-
-
-   public Map<Fqn<?>, Object> findAll(String id) throws PojoCacheException
-   {
-      return findAll(Fqn.fromString(id));
-   }
-
-   public Map<Fqn<?>, Object> findAll(Fqn<?> id) throws PojoCacheException
-   {
-      // Should produce "/"
-      if (id == null) id = Fqn.ROOT;
-
-      try
-      {
-         return delegate_.findObjects(id);
-      }
-      catch (CacheException e)
-      {
-         throw new PojoCacheException("findAll " + id + " failed", e);
-      }
-   }
-
-   public String getVersion()
-   {
-      return Version.printVersion();
-   }
-
-   public void create() throws PojoCacheException
-   {
-      log_.info("PojoCache version: " + getVersion());
-      try
-      {
-         cache.create();
-      }
-      catch (Exception e)
-      {
-         throw new PojoCacheException("PojoCache create exception", e);
-      }
-
-      hasCreate_ = true;
-   }
-
-   public void start() throws PojoCacheException
-   {
-      if (!hasCreate_)
-      {
-         create();
-      }
-
-      try
-      {
-         log_.info("PojoCache version: " + getVersion());
-         cache.start();
-      }
-      catch (Exception e)
-      {
-         throw new PojoCacheException("Failed starting " + e, e);
-      }
-   }
-
-   public void stop() throws PojoCacheException
-   {
-      cache.stop();
-   }
-
-   public void destroy() throws PojoCacheException
-   {
-      cache.destroy();
-   }
-
-   public Collection<Object> getListeners()
-   {
-      return listenerAdaptor.getListeners();
-   }
-
-   public void addListener(Object listener)
-   {
-      addListener(listener, null);
-   }
-
-   public void addListener(Object listener, Pattern pattern)
-   {
-      // Add and remove listner operations must be serialized to ensure that
-      // the adaptor is always present only once, when at least one listener
-      // is registered.
-      synchronized (listenerAdaptor)
-      {
-         try
-         {
-            boolean wasEmpty = listenerAdaptor.isEmpty();
-            listenerAdaptor.addListener(listener, pattern);
-            if (wasEmpty)
-               cache.addCacheListener(listenerAdaptor);
-         }
-         catch (IllegalArgumentException e)
-         {
-            // simplify stack trace for user
-            e.fillInStackTrace();
-            throw e;
-         }
-      }
-   }
-
-   public void removeListener(Object listener)
-   {
-      synchronized (listenerAdaptor)
-      {
-         listenerAdaptor.removeListener(listener);
-         if (listenerAdaptor.isEmpty())
-            cache.removeCacheListener(listenerAdaptor);
-      }
-   }
-
-   public PojoCacheThreadContext getThreadContext()
-   {
-      return threadContext;
-   }
-
-   public Cache<Object,Object> getCache()
-   {
-      return cache;
-   }
-
-   /**
-    * Obtain a cache aop type for user to traverse the defined "primitive" types in aop.
-    * Note that this is not a synchronized call now for speed optimization.
-    *
-    * @param clazz The original pojo class
-    * @return CachedType
-    */
-   public synchronized CachedType getCachedType(Class clazz)
-   {
-      CachedType type = (CachedType) cachedTypes_.get(clazz);
-      if (type == null)
-      {
-         type = new CachedType(clazz);
-         cachedTypes_.put(clazz, type);
-         return type;
-      }
-      else
-      {
-         return type;
-      }
-   }
-
-   public String toString()
-   {
-      return getClass().getName() +
-              " cache=" + cache +
-              " delegate=" + delegate_ +
-              " types=" + cachedTypes_.size();
-   }
-}

Copied: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/PojoCacheImpl.java (from rev 6374, pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheImpl.java)
===================================================================
--- pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/PojoCacheImpl.java	                        (rev 0)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/PojoCacheImpl.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -0,0 +1,418 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+package org.jboss.cache.pojo.impl;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.WeakHashMap;
+import java.util.regex.Pattern;
+
+import javax.transaction.Status;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.Cache;
+import org.jboss.cache.CacheException;
+import org.jboss.cache.CacheSPI;
+import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.Version;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.factories.XmlConfigurationParser;
+import org.jboss.cache.pojo.PojoCache;
+import org.jboss.cache.pojo.PojoCacheException;
+import org.jboss.cache.pojo.PojoCacheThreadContext;
+import org.jboss.cache.pojo.Reference;
+import org.jboss.cache.pojo.interceptors.PojoTxSynchronizationHandler;
+import org.jboss.cache.transaction.BatchModeTransactionManager;
+
+/**
+ * Implementation class for PojoCache interface
+ *
+ * @author Ben Wang
+ * @version $Id$
+ */
+public class PojoCacheImpl implements PojoCache
+{
+   private CacheSPI<Object, Object> cache = null;
+   protected final Log log_ = LogFactory.getLog(PojoCacheImpl.this.getClass());
+   private PojoCacheDelegate delegate_;
+   // Class -> CachedType
+   // use WeakHashMap to allow class reloading
+   private Map cachedTypes_ = new WeakHashMap();
+   private boolean hasCreate_ = false;
+   private CacheListenerAdaptor listenerAdaptor = new CacheListenerAdaptor(this);
+   private PojoCacheThreadContext threadContext = new PojoCacheThreadContextImpl();
+
+   public PojoCacheImpl(String configStr, boolean toStart)
+   {
+      try
+      {
+         //         cache_ = new PojoTreeCache();
+         //         cache_.setConfiguration(new XmlConfigurationParser().parseFile(configStr));
+
+         XmlConfigurationParser parser = new XmlConfigurationParser();
+         Configuration expected = parser.parseFile(configStr);
+
+         init(expected, toStart);
+      }
+      catch (Exception e)
+      {
+         throw new PojoCacheException("Failed to start " + configStr, e);
+      }
+   }
+
+   public PojoCacheImpl(Configuration config, boolean toStart)
+   {
+      init(config, toStart);
+   }
+
+   private void init(Configuration config, boolean toStart)
+   {
+      try
+      {
+         cache = (CacheSPI<Object, Object>) DefaultCacheFactory.getInstance().createCache(config, toStart);
+      }
+      catch (Exception e)
+      {
+         throw new PojoCacheException("init " + config + " failed", e);
+      }
+
+      delegate_ = new PojoCacheDelegate(this);
+   }
+
+   public CacheSPI<Object, Object> getCacheSPI()
+   {
+      return cache;
+   }
+
+   public Object attach(String id, Object pojo) throws PojoCacheException
+   {
+      return attach(Fqn.fromString(id), pojo);
+   }
+
+   public Object attach(Fqn<?> id, Object pojo) throws PojoCacheException
+   {
+      return attach(id, pojo, null, null);
+   }
+
+   public Object attach(Fqn<?> id, Object pojo, String field, Object source) throws PojoCacheException
+   {
+      TransactionManager tm = getTransactionManager();
+      boolean createdTransaction = setupTransaction(tm);
+      try
+      {
+         Object obj = delegate_.putObject(id, pojo, field, source);
+         return obj;
+      }
+      catch (Throwable t)
+      {
+         setRollbackOnly(tm);
+         throw new PojoCacheException("attach failed " + id, t);
+      }
+      finally
+      {
+         if (createdTransaction)
+            endTransaction(tm, id);
+      }
+   }
+
+   public Object detach(Fqn<?> id, String field, Object source) throws PojoCacheException
+   {
+      TransactionManager tm = getTransactionManager();
+      boolean createdTransaction = setupTransaction(tm);
+      try
+      {
+         Object obj = delegate_.removeObject(id, field, source);
+         return obj;
+      }
+      catch (Throwable t)
+      {
+         setRollbackOnly(tm);
+         throw new PojoCacheException("detach failed " + id, t);
+      }
+      finally
+      {
+         if (createdTransaction)
+            endTransaction(tm, id);
+      }
+   }
+
+   private void endTransaction(TransactionManager tm, Fqn<?> id)
+   {
+      try
+      {
+         switch (tm.getStatus())
+         {
+            case Status.STATUS_PREPARING:
+            case Status.STATUS_PREPARED:
+            case Status.STATUS_ACTIVE:
+               tm.commit();
+               break;
+            case Status.STATUS_MARKED_ROLLBACK:
+               tm.rollback();
+               break;
+         }
+      }
+      catch (Throwable t)
+      {
+         if (log_.isWarnEnabled())
+            log_.warn("Could not end transaction for operation on: " + id, t);
+      }
+   }
+
+   private void setRollbackOnly(TransactionManager tm)
+   {
+      try
+      {
+         if (tm.getStatus() != Status.STATUS_MARKED_ROLLBACK)
+            tm.setRollbackOnly();
+      }
+      catch (Throwable t)
+      {
+         if (log_.isWarnEnabled())
+            log_.warn("Could not rollback transaction!", t);
+      }
+   }
+
+   private boolean setupTransaction(TransactionManager tm)
+   {
+      boolean created = false;
+      try
+      {
+         Transaction transaction = tm.getTransaction();
+         if (transaction == null)
+         {
+            tm.begin();
+            transaction = tm.getTransaction();
+            created = true;
+         }
+
+         transaction.registerSynchronization(PojoTxSynchronizationHandler.create());
+      }
+      catch (Exception e)
+      {
+         throw new PojoCacheException("Error creating transaction", e);
+      }
+
+      return created;
+   }
+
+   private TransactionManager getTransactionManager()
+   {
+      TransactionManager tm = cache.getConfiguration().getRuntimeConfig().getTransactionManager();
+      if (tm == null)
+         tm = BatchModeTransactionManager.getInstance();
+
+      return tm;
+   }
+
+   public Object detach(String id) throws PojoCacheException
+   {
+      return detach(Fqn.fromString(id));
+   }
+
+
+
+   public Object detach(Fqn<?> id) throws PojoCacheException
+   {
+      return detach(id, null, null);
+   }
+
+   public Fqn<?> getInternalFqn(Object object)
+   {
+      return delegate_.getInternalFqn(object);
+   }
+
+   public Collection<Reference> getReferences(Object object)
+   {
+      return delegate_.getReferences(object);
+   }
+
+   public boolean exists(Fqn<?> id)
+   {
+      return delegate_.exists(id);
+   }
+
+   public Object find(String id) throws PojoCacheException
+   {
+      return find(Fqn.fromString(id));
+   }
+
+   public Object find(Fqn<?> id) throws PojoCacheException
+   {
+      try
+      {
+         return find(id, null, null);
+      }
+      catch (CacheException e)
+      {
+         throw new PojoCacheException("find " + id + " failed ", e);
+      }
+   }
+
+   public Object find(Fqn<?> id, String field, Object source) throws CacheException
+   {
+      return delegate_.getObject(id, field, source);
+   }
+
+
+   public Map<Fqn<?>, Object> findAll(String id) throws PojoCacheException
+   {
+      return findAll(Fqn.fromString(id));
+   }
+
+   public Map<Fqn<?>, Object> findAll(Fqn<?> id) throws PojoCacheException
+   {
+      // Should produce "/"
+      if (id == null) id = Fqn.ROOT;
+
+      try
+      {
+         return delegate_.findObjects(id);
+      }
+      catch (CacheException e)
+      {
+         throw new PojoCacheException("findAll " + id + " failed", e);
+      }
+   }
+
+   public String getVersion()
+   {
+      return Version.printVersion();
+   }
+
+   public void create() throws PojoCacheException
+   {
+      log_.info("PojoCache version: " + getVersion());
+      try
+      {
+         cache.create();
+      }
+      catch (Exception e)
+      {
+         throw new PojoCacheException("PojoCache create exception", e);
+      }
+
+      hasCreate_ = true;
+   }
+
+   public void start() throws PojoCacheException
+   {
+      if (!hasCreate_)
+      {
+         create();
+      }
+
+      try
+      {
+         log_.info("PojoCache version: " + getVersion());
+         cache.start();
+      }
+      catch (Exception e)
+      {
+         throw new PojoCacheException("Failed starting " + e, e);
+      }
+   }
+
+   public void stop() throws PojoCacheException
+   {
+      cache.stop();
+   }
+
+   public void destroy() throws PojoCacheException
+   {
+      cache.destroy();
+   }
+
+   public Collection<Object> getListeners()
+   {
+      return listenerAdaptor.getListeners();
+   }
+
+   public void addListener(Object listener)
+   {
+      addListener(listener, null);
+   }
+
+   public void addListener(Object listener, Pattern pattern)
+   {
+      // Add and remove listner operations must be serialized to ensure that
+      // the adaptor is always present only once, when at least one listener
+      // is registered.
+      synchronized (listenerAdaptor)
+      {
+         try
+         {
+            boolean wasEmpty = listenerAdaptor.isEmpty();
+            listenerAdaptor.addListener(listener, pattern);
+            if (wasEmpty)
+               cache.addCacheListener(listenerAdaptor);
+         }
+         catch (IllegalArgumentException e)
+         {
+            // simplify stack trace for user
+            e.fillInStackTrace();
+            throw e;
+         }
+      }
+   }
+
+   public void removeListener(Object listener)
+   {
+      synchronized (listenerAdaptor)
+      {
+         listenerAdaptor.removeListener(listener);
+         if (listenerAdaptor.isEmpty())
+            cache.removeCacheListener(listenerAdaptor);
+      }
+   }
+
+   public PojoCacheThreadContext getThreadContext()
+   {
+      return threadContext;
+   }
+
+   public Cache<Object,Object> getCache()
+   {
+      return cache;
+   }
+
+   /**
+    * Obtain a cache aop type for user to traverse the defined "primitive" types in aop.
+    * Note that this is not a synchronized call now for speed optimization.
+    *
+    * @param clazz The original pojo class
+    * @return CachedType
+    */
+   public synchronized CachedType getCachedType(Class clazz)
+   {
+      CachedType type = (CachedType) cachedTypes_.get(clazz);
+      if (type == null)
+      {
+         type = new CachedType(clazz);
+         cachedTypes_.put(clazz, type);
+         return type;
+      }
+      else
+      {
+         return type;
+      }
+   }
+
+   public String toString()
+   {
+      return getClass().getName() +
+              " cache=" + cache +
+              " delegate=" + delegate_ +
+              " types=" + cachedTypes_.size();
+   }
+}

Deleted: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/PojoInstance.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoInstance.java	2008-07-16 17:30:08 UTC (rev 6310)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/PojoInstance.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -1,160 +0,0 @@
-/*
- * JBoss, the OpenSource J2EE webOS
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package org.jboss.cache.pojo.impl;
-
-import org.jboss.cache.Fqn;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * POJO class metadata information.
- * When an object is looked up or put in PojoCache, this object will be advised with a CacheFieldInterceptor.
- * The underlying cache stores a reference to this object (for example to update the instance variables, etc.).
- * Since this reference need to be transactional but never replicated (the reference is only valid
- * within the VM this reference is thus stored into an PojoReference (as a transient field).
- * In addition, this instance also serves as a metadata for PojoCache. E.g., it has a reference counting for
- * multiple references and reference FQN.
- *
- * @author Ben Wang
- */
-public class PojoInstance implements Serializable // Externalizable is no more efficient
-{
-   //    protected static Log log=LogFactory.getLog(PojoReference.class.getLastElementAsString());
-   public static final String KEY = InternalConstant.POJOCACHE_KEY_PREFIX + "PojoInstance";
-   public static final int INITIAL_COUNTER_VALUE = -1;
-
-   static final long serialVersionUID = 6492134565825613209L;
-
-   // The instance is transient to avoid replication outside the VM
-   private transient Object instance_;
-
-   // If not null, it signifies that this is a reference that points to this fqn.
-   // Note that this will get replicated.
-   private String internalFqn_ = null;
-
-   // Reference counting. THis will get replicated as well. This keep track of number of
-   // other instances that referenced this fqn.
-   private int refCount_ = INITIAL_COUNTER_VALUE;
-
-   // List of fqns that reference this fqn. Assume list size is not big since it may not be efficient.
-   private List<Fqn> referencedBy_ = null;
-   private Class clazz_ = null;
-   private transient PojoUtil util_ = new PojoUtil();
-
-   public PojoInstance()
-   {
-   }
-
-   public PojoInstance(Object instance)
-   {
-      set(instance);
-   }
-
-   public void setPojoClass(Class clazz)
-   {
-      clazz_ = clazz;
-   }
-
-   public Class getPojoClass()
-   {
-      return clazz_;
-   }
-
-   public Object get()
-   {
-      return instance_;
-   }
-
-   public void set(Object instance)
-   {
-      instance_ = instance;
-   }
-
-   public String getInternalFqn()
-   {
-      return internalFqn_;
-   }
-
-   public void setInternalFqn(String refFqn)
-   {
-      internalFqn_ = refFqn;
-   }
-
-   public void removeInternalFqn()
-   {
-      internalFqn_ = null;
-   }
-
-   synchronized public int incrementRefCount(Fqn sourceFqn)
-   {
-      if (sourceFqn == null)
-      {
-         throw new IllegalStateException("PojoInstance.incrementRefCount(): null sourceFqn");
-      }
-
-      if (referencedBy_ == null)
-      {
-         referencedBy_ = new ArrayList();
-      }
-
-      if (util_ == null) util_ = new PojoUtil();
-      refCount_ = util_.incrementReferenceCount(sourceFqn, refCount_, referencedBy_);
-//      referencedBy_.add(sourceFqn);
-
-//      refCount_ += 1;
-//logger_.info("incrementRefCount(): current ref count " +refCount_);
-      return refCount_;
-   }
-
-   synchronized public int decrementRefCount(Fqn sourceFqn)
-   {
-      if (sourceFqn == null)
-      {
-         throw new IllegalStateException("PojoInstance.incrementRefCount(): null sourceFqn");
-      }
-
-      if (!referencedBy_.contains(sourceFqn))
-         throw new IllegalStateException("PojoReference.decrementRefCount(): source fqn: " +
-                                         sourceFqn + " is not present.");
-
-      if (util_ == null) util_ = new PojoUtil();
-      refCount_ = util_.decrementReferenceCount(sourceFqn, refCount_, referencedBy_);
-//      referencedBy_.remove(sourceFqn);
-
-//      refCount_ -= 1;
-//logger_.info("decrementRefCount(): current ref count " +refCount_);
-      return refCount_;
-   }
-
-   synchronized public int getRefCount()
-   {
-      return refCount_;
-   }
-
-   public List<Fqn> getReferences()
-   {
-      return Collections.unmodifiableList(referencedBy_);
-   }
-
-   synchronized public Fqn getAndRemoveFirstFqnInList()
-   {
-      return (Fqn) referencedBy_.remove(0);
-   }
-
-   synchronized public void addXFqnIntoList(Fqn fqn)
-   {
-      referencedBy_.add(0, fqn);
-   }
-
-   public String toString()
-   {
-      return "PI[fqn=" + internalFqn_ + " ref=" + refCount_ + " class=" + clazz_.getName() + "]";
-   }
-}

Copied: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/PojoInstance.java (from rev 6551, pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoInstance.java)
===================================================================
--- pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/PojoInstance.java	                        (rev 0)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/PojoInstance.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -0,0 +1,119 @@
+/*
+ * JBoss, the OpenSource J2EE webOS
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jboss.cache.pojo.impl;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.jboss.cache.pojo.Reference;
+
+/**
+ * POJO class metadata information.
+ * When an object is looked up or put in PojoCache, this object will be advised with a CacheFieldInterceptor.
+ * The underlying cache stores a reference to this object (for example to update the instance variables, etc.).
+ * Since this reference need to be transactional but never replicated (the reference is only valid
+ * within the VM this reference is thus stored into an PojoReference (as a transient field).
+ * In addition, this instance also serves as a metadata for PojoCache. E.g., it has a reference counting for
+ * multiple references and reference FQN.
+ *
+ * @author Ben Wang
+ */
+public class PojoInstance implements Serializable // Externalizable is no more efficient
+{
+   //    protected static Log log=LogFactory.getLog(PojoReference.class.getLastElementAsString());
+   public static final String KEY = InternalConstant.POJOCACHE_KEY_PREFIX + "PojoInstance";
+   public static final int INITIAL_COUNTER_VALUE = -1;
+
+   static final long serialVersionUID = 6492134565825613209L;
+
+   // The instance is transient to avoid replication outside the VM
+   private transient Object instance_;
+
+   // Reference counting. THis will get replicated as well. This keep track of number of
+   // other instances that referenced this fqn.
+   private int refCount_ = INITIAL_COUNTER_VALUE;
+
+   // List of fqns that reference this fqn.
+   private final Set<Reference> referencedBy_ = new HashSet<Reference>(4);
+   private Class<?> clazz_ = null;
+   private transient PojoUtil util_ = new PojoUtil();
+
+   public PojoInstance()
+   {
+   }
+
+   public PojoInstance(Object instance)
+   {
+      set(instance);
+   }
+
+   public void setPojoClass(Class clazz)
+   {
+      clazz_ = clazz;
+   }
+
+   public Class getPojoClass()
+   {
+      return clazz_;
+   }
+
+   public Object get()
+   {
+      return instance_;
+   }
+
+   public void set(Object instance)
+   {
+      instance_ = instance;
+   }
+
+   synchronized public int incrementRefCount(Reference reference)
+   {
+      if (reference == null || reference.getFqn() == null)
+      {
+         throw new IllegalStateException("PojoInstance.incrementRefCount(): null sourceFqn");
+      }
+
+      if (util_ == null) util_ = new PojoUtil();
+      refCount_ = util_.incrementReferenceCount(reference, refCount_, referencedBy_);
+      return refCount_;
+   }
+
+   synchronized public int decrementRefCount(Reference reference)
+   {
+      if (reference == null || reference.getFqn() == null)
+      {
+         throw new IllegalStateException("PojoInstance.incrementRefCount(): null sourceFqn");
+      }
+
+      if (!referencedBy_.contains(reference))
+         throw new IllegalStateException("PojoReference.decrementRefCount(): reference: " +
+                                         reference + " is not present.");
+
+      if (util_ == null) util_ = new PojoUtil();
+      refCount_ = util_.decrementReferenceCount(reference, refCount_, referencedBy_);
+      return refCount_;
+   }
+
+   synchronized public int getRefCount()
+   {
+      return refCount_;
+   }
+
+   public synchronized Collection<Reference> getReferences()
+   {
+      return Collections.unmodifiableCollection(new HashSet<Reference>(referencedBy_));
+   }
+
+   public String toString()
+   {
+      return "PI[ref=" + refCount_ + " class=" + clazz_.getName() + "]";
+   }
+}

Deleted: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/PojoUtil.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoUtil.java	2008-07-16 17:30:08 UTC (rev 6310)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/PojoUtil.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -1,201 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-
-package org.jboss.cache.pojo.impl;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.List;
-
-import org.jboss.aop.InstanceAdvisor;
-import org.jboss.aop.advice.Interceptor;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.pojo.PojoCacheException;
-import org.jboss.cache.pojo.collection.CachedArray;
-import org.jboss.cache.pojo.collection.CachedArrayRegistry;
-import org.jboss.cache.pojo.interceptors.PojoTxSynchronizationHandler;
-import org.jboss.cache.pojo.interceptors.dynamic.AbstractCollectionInterceptor;
-import org.jboss.cache.pojo.interceptors.dynamic.CacheFieldInterceptor;
-import org.jboss.cache.pojo.util.MethodCall;
-
-/**
- * Utility class for method wrappers that we are interested to rollback (i.e., rollback).
- *
- * @author Ben Wang
- * @version $Id$
- */
-public class PojoUtil
-{
-   public void attachInterceptor(Object pojo, InstanceAdvisor advisor, Interceptor interceptor)
-   {
-      _attachInterceptor(pojo, advisor, interceptor);
-      Method method = MethodDeclarations.undoAttachInterceptor;
-      MethodCall mc = new MethodCall(method, new Object[] {pojo, advisor, interceptor}, this);
-      addUndo(mc);
-   }
-
-   public void detachInterceptor(InstanceAdvisor advisor, Interceptor interceptor)
-   {
-      _detachInterceptor(advisor, interceptor);
-      Method method = MethodDeclarations.undoDetachInterceptor;
-      MethodCall mc = new MethodCall(method, new Object[] {advisor, interceptor}, this);
-      addUndo(mc);
-   }
-
-   private void addUndo(MethodCall mc)
-   {
-      PojoTxSynchronizationHandler handler = PojoTxSynchronizationHandler.current();
-      if (handler != null)
-         handler.addToList(mc);
-   }
-
-   public void detachCollectionInterceptor(AbstractCollectionInterceptor interceptor) {
-      interceptor.detach(true);
-      Method method = MethodDeclarations.undoDetachCollectionInterceptor;
-      MethodCall mc = new MethodCall(method, new Object[] {interceptor}, this);
-      addUndo(mc);
-   }
-
-   public void attachArray(Object array, CachedArray cached) {
-      CachedArrayRegistry.register(array, cached);
-      Method method = MethodDeclarations.undoAttachArray;
-      MethodCall mc = new MethodCall(method, new Object[] {array, cached}, this);
-      addUndo(mc);
-   }
-
-   public void detachArray(Object array, CachedArray cached) {
-      CachedArrayRegistry.unregister(array);
-      Method method = MethodDeclarations.undoDetachArray;
-      MethodCall mc = new MethodCall(method, new Object[] {array, cached}, this);
-      addUndo(mc);
-   }
-
-   public void undoAttachInterceptor(Object pojo, InstanceAdvisor advisor, Interceptor interceptor)
-   {
-      _detachInterceptor(advisor, interceptor);
-   }
-
-   public void undoDetachInterceptor(InstanceAdvisor advisor, Interceptor interceptor)
-   {
-      Object pojo = ((CacheFieldInterceptor) interceptor).getAopInstance().get();
-      if (pojo == null)
-      {
-         throw new PojoCacheException("PojoUtil.detachInterceptor(): null pojo");
-      }
-
-      _attachInterceptor(pojo, advisor, interceptor);
-   }
-
-   public void undoDetachCollectionInterceptor(AbstractCollectionInterceptor interceptor) {
-      interceptor.attach(null, false);
-   }
-
-   public void undoAttachArray(Object array, CachedArray cached) {
-      CachedArrayRegistry.unregister(array);
-   }
-
-   public void undoDetachArray(Object array, CachedArray cached) {
-      CachedArrayRegistry.register(array, cached);
-   }
-
-   public void inMemorySubstitution(Object obj, Field field, Object newValue)
-   {
-      Method method = MethodDeclarations.undoInMemorySubstitution;
-      Object[] args;
-      try
-      {
-         args = new Object[]{obj, field, field.get(obj)};
-      }
-      catch (Throwable t)
-      {
-         throw new PojoCacheException("Severe error building undo list", t);
-      }
-
-      _inMemorySubstitution(obj, field, newValue);
-
-      MethodCall mc = new MethodCall(method, args, this);
-      addUndo(mc);
-   }
-
-   public void undoInMemorySubstitution(Object obj, Field field, Object oldValue)
-   {
-      _inMemorySubstitution(obj, field, oldValue);
-   }
-
-   private void _attachInterceptor(Object pojo, InstanceAdvisor advisor, Interceptor interceptor)
-   {
-      advisor.appendInterceptor(interceptor);
-   }
-
-   private void _inMemorySubstitution(Object obj, Field field, Object newValue)
-   {
-      try
-      {
-         field.set(obj, newValue);
-      }
-      catch (IllegalAccessException e)
-      {
-         throw new PojoCacheException(
-               "PojoUtil.inMemorySubstitution(): Can't swap out the class of field \" " +
-               "+field.getLastElementAsString()," + e);
-      }
-   }
-
-   private void _detachInterceptor(InstanceAdvisor advisor, Interceptor interceptor)
-   {
-      advisor.removeInterceptor(interceptor.getName());
-      // retrieve pojo
-      Object pojo = ((CacheFieldInterceptor) interceptor).getAopInstance().get();
-
-      if (pojo == null)
-      {
-         throw new PojoCacheException("PojoUtil.detachInterceptor(): null pojo");
-      }
-   }
-
-   public int incrementReferenceCount(Fqn<?> sourceFqn, int count, List<?> refList)
-   {
-      int ret = _incrementReferenceCount(sourceFqn, count, refList);
-      Method method = MethodDeclarations.undoIncrementReferenceCount;
-      Object[] args = new Object[]{sourceFqn, count, refList};
-      MethodCall mc = new MethodCall(method, args, this);
-      addUndo(mc);
-      return ret;
-   }
-
-   public int undoIncrementReferenceCount(Fqn sourceFqn, int count, List refList)
-   {
-      return _decrementReferenceCount(sourceFqn, count, refList);
-   }
-
-   private int _incrementReferenceCount(Fqn sourceFqn, int count, List refList)
-   {
-      refList.add(sourceFqn);
-      return count + 1;
-   }
-
-   public int decrementReferenceCount(Fqn<?> sourceFqn, int count, List<?> refList)
-   {
-      int ret = _decrementReferenceCount(sourceFqn, count, refList);
-      Method method = MethodDeclarations.undoDecrementReferenceCount;
-      Object[] args = new Object[]{sourceFqn, count, refList};
-      MethodCall mc = new MethodCall(method, args, this);
-      addUndo(mc);
-      return ret;
-   }
-
-   public int undoDecrementReferenceCount(Fqn sourceFqn, int count, List refList)
-   {
-      return _incrementReferenceCount(sourceFqn, count, refList);
-   }
-
-   private int _decrementReferenceCount(Fqn sourceFqn, int count, List refList)
-   {
-      refList.remove(sourceFqn);
-      return count - 1;
-   }
-}

Copied: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/PojoUtil.java (from rev 6374, pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoUtil.java)
===================================================================
--- pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/PojoUtil.java	                        (rev 0)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/PojoUtil.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -0,0 +1,203 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+package org.jboss.cache.pojo.impl;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Set;
+
+import org.jboss.aop.InstanceAdvisor;
+import org.jboss.aop.advice.Interceptor;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.pojo.PojoCacheException;
+import org.jboss.cache.pojo.Reference;
+import org.jboss.cache.pojo.collection.CachedArray;
+import org.jboss.cache.pojo.collection.CachedArrayRegistry;
+import org.jboss.cache.pojo.interceptors.PojoTxSynchronizationHandler;
+import org.jboss.cache.pojo.interceptors.dynamic.AbstractCollectionInterceptor;
+import org.jboss.cache.pojo.interceptors.dynamic.CacheFieldInterceptor;
+import org.jboss.cache.pojo.util.MethodCall;
+
+/**
+ * Utility class for method wrappers that we are interested to rollback (i.e., rollback).
+ *
+ * @author Ben Wang
+ * @version $Id$
+ */
+public class PojoUtil
+{
+   public void attachInterceptor(Object pojo, InstanceAdvisor advisor, Interceptor interceptor)
+   {
+      _attachInterceptor(pojo, advisor, interceptor);
+      Method method = MethodDeclarations.undoAttachInterceptor;
+      MethodCall mc = new MethodCall(method, new Object[] {pojo, advisor, interceptor}, this);
+      addUndo(mc);
+   }
+
+   public void detachInterceptor(InstanceAdvisor advisor, Interceptor interceptor)
+   {
+      _detachInterceptor(advisor, interceptor);
+      Method method = MethodDeclarations.undoDetachInterceptor;
+      MethodCall mc = new MethodCall(method, new Object[] {advisor, interceptor}, this);
+      addUndo(mc);
+   }
+
+   private void addUndo(MethodCall mc)
+   {
+      PojoTxSynchronizationHandler handler = PojoTxSynchronizationHandler.current();
+      if (handler != null)
+         handler.addToList(mc);
+   }
+
+   public void detachCollectionInterceptor(AbstractCollectionInterceptor interceptor) {
+      interceptor.detach(true);
+      Method method = MethodDeclarations.undoDetachCollectionInterceptor;
+      MethodCall mc = new MethodCall(method, new Object[] {interceptor}, this);
+      addUndo(mc);
+   }
+
+   public void attachArray(Object array, CachedArray cached) {
+      CachedArrayRegistry.register(array, cached);
+      Method method = MethodDeclarations.undoAttachArray;
+      MethodCall mc = new MethodCall(method, new Object[] {array, cached}, this);
+      addUndo(mc);
+   }
+
+   public void detachArray(Object array, CachedArray cached) {
+      CachedArrayRegistry.unregister(array);
+      Method method = MethodDeclarations.undoDetachArray;
+      MethodCall mc = new MethodCall(method, new Object[] {array, cached}, this);
+      addUndo(mc);
+   }
+
+   public void undoAttachInterceptor(Object pojo, InstanceAdvisor advisor, Interceptor interceptor)
+   {
+      _detachInterceptor(advisor, interceptor);
+   }
+
+   public void undoDetachInterceptor(InstanceAdvisor advisor, Interceptor interceptor)
+   {
+      Object pojo = ((CacheFieldInterceptor) interceptor).getAopInstance().get();
+      if (pojo == null)
+      {
+         throw new PojoCacheException("PojoUtil.detachInterceptor(): null pojo");
+      }
+
+      _attachInterceptor(pojo, advisor, interceptor);
+   }
+
+   public void undoDetachCollectionInterceptor(AbstractCollectionInterceptor interceptor) {
+      interceptor.attach(null, false);
+   }
+
+   public void undoAttachArray(Object array, CachedArray cached) {
+      CachedArrayRegistry.unregister(array);
+   }
+
+   public void undoDetachArray(Object array, CachedArray cached) {
+      CachedArrayRegistry.register(array, cached);
+   }
+
+   public void inMemorySubstitution(Object obj, Field field, Object newValue)
+   {
+      Method method = MethodDeclarations.undoInMemorySubstitution;
+      Object[] args;
+      try
+      {
+         args = new Object[]{obj, field, field.get(obj)};
+      }
+      catch (Throwable t)
+      {
+         throw new PojoCacheException("Severe error building undo list", t);
+      }
+
+      _inMemorySubstitution(obj, field, newValue);
+
+      MethodCall mc = new MethodCall(method, args, this);
+      addUndo(mc);
+   }
+
+   public void undoInMemorySubstitution(Object obj, Field field, Object oldValue)
+   {
+      _inMemorySubstitution(obj, field, oldValue);
+   }
+
+   private void _attachInterceptor(Object pojo, InstanceAdvisor advisor, Interceptor interceptor)
+   {
+      advisor.appendInterceptor(interceptor);
+   }
+
+   private void _inMemorySubstitution(Object obj, Field field, Object newValue)
+   {
+      try
+      {
+         field.set(obj, newValue);
+      }
+      catch (IllegalAccessException e)
+      {
+         throw new PojoCacheException(
+               "PojoUtil.inMemorySubstitution(): Can't swap out the class of field \" " +
+               "+field.getLastElementAsString()," + e);
+      }
+   }
+
+   private void _detachInterceptor(InstanceAdvisor advisor, Interceptor interceptor)
+   {
+      advisor.removeInterceptor(interceptor.getName());
+      // retrieve pojo
+      Object pojo = ((CacheFieldInterceptor) interceptor).getAopInstance().get();
+
+      if (pojo == null)
+      {
+         throw new PojoCacheException("PojoUtil.detachInterceptor(): null pojo");
+      }
+   }
+
+   public int incrementReferenceCount(Reference reference, int count, Set<Reference> referencedBy_)
+   {
+      int ret = _incrementReferenceCount(reference, count, referencedBy_);
+      Method method = MethodDeclarations.undoIncrementReferenceCount;
+      Object[] args = new Object[]{reference, count, referencedBy_};
+      MethodCall mc = new MethodCall(method, args, this);
+      addUndo(mc);
+      return ret;
+   }
+
+   public int undoIncrementReferenceCount(Reference reference, int count, Set<Reference> refList)
+   {
+      return _decrementReferenceCount(reference, count, refList);
+   }
+
+   private int _incrementReferenceCount(Reference reference, int count, Set<Reference> referencedBy_)
+   {
+      referencedBy_.add(reference);
+      return count + 1;
+   }
+
+   public int decrementReferenceCount(Reference reference, int count, Set<Reference> referencedBy_)
+   {
+      int ret = _decrementReferenceCount(reference, count, referencedBy_);
+      Method method = MethodDeclarations.undoDecrementReferenceCount;
+      Object[] args = new Object[]{reference, count, referencedBy_};
+      MethodCall mc = new MethodCall(method, args, this);
+      addUndo(mc);
+      return ret;
+   }
+
+   public int undoDecrementReferenceCount(Reference reference, int count, Set<Reference> refList)
+   {
+      return _incrementReferenceCount(reference, count, refList);
+   }
+
+   private int _decrementReferenceCount(Reference reference, int count, Set<Reference> referencedBy_)
+   {
+      referencedBy_.remove(reference);
+      return count - 1;
+   }
+}

Copied: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/ReferenceImpl.java (from rev 6374, pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/ReferenceImpl.java)
===================================================================
--- pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/ReferenceImpl.java	                        (rev 0)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/ReferenceImpl.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -0,0 +1,110 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.cache.pojo.impl;
+
+import java.io.Serializable;
+
+import net.jcip.annotations.Immutable;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.pojo.Reference;
+
+/**
+ * A reference from an attached object to another attached object. This class also contains the name
+ * of the field that contains the reference.
+ *
+ * @author Dan Berindei <dan.berindei at gmail.com>
+ */
+ at Immutable
+public final class ReferenceImpl implements Reference, Serializable
+{
+   private static final long serialVersionUID = 2647262858847953704L;
+
+   private Fqn<?> fqn;
+   private String key;
+
+   public ReferenceImpl(Fqn<?> fqn)
+   {
+      this(fqn, null);
+   }
+
+   /**
+    * @param fqn <code>Fqn</code> of the referring node. Cannot be <code>null</code>.
+    * @param key Name of the field, index in the field or key in the collection that is containing the reference.
+    */
+   public ReferenceImpl(Fqn<?> fqn, String key)
+   {
+      if (fqn == null)
+         throw new IllegalArgumentException("Fqn can not be null!!");
+
+      this.fqn = fqn;
+      this.key = key;
+   }
+
+   public String getKey()
+   {
+      return key;
+   }
+
+   public Fqn<?> getFqn()
+   {
+      return fqn;
+   }
+
+   private boolean equals(Object o1, Object o2)
+   {
+      if (o1 == o2)
+         return true;
+
+      if (o1 != null && o1.equals(o2))
+         return true;
+
+      return false;
+   }
+
+   @Override
+   public int hashCode()
+   {
+      int result = 629 * fqn.hashCode();
+
+      if (key != null)
+         result = 37 * result + key.hashCode();
+
+      return result;
+   }
+
+   @Override
+   public boolean equals(Object o)
+   {
+      if (o instanceof Reference)
+         return equals(((ReferenceImpl) o).fqn, fqn) && equals(((ReferenceImpl) o).key, key);
+
+      return false;
+   }
+
+   @Override
+   public String toString()
+   {
+      return "Reference[fqn=" + fqn + " field=" + key + "]";
+   }
+}
\ No newline at end of file

Deleted: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/Referrer.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/Referrer.java	2008-07-16 17:30:08 UTC (rev 6310)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/Referrer.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -1,89 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-
-package org.jboss.cache.pojo.impl;
-
-import org.jboss.cache.Fqn;
-
-/**
- * A referrer node refers to an internal node.
- * 
- * @author Jason T. Greene
- */
-final class Referrer
-{
-   private Fqn fqn;
-   private String field;
-
-   Referrer(Fqn fqn)
-   {
-      this(fqn, null);
-   }
-   
-   Referrer(Fqn fqn, String field)
-   {
-      if (fqn == null)
-         throw new IllegalArgumentException("Fqn can not be null!!");
-      
-      this.fqn = fqn;
-      this.field = field;
-   }
-
-   public String getField()
-   {
-      return field;
-   }
-
-   public Fqn getFqn()
-   {
-      return fqn;
-   }
-   
-   private boolean equals(Object o1, Object o2)
-   {
-      if (o1 == o2)
-         return true;
-      
-      if (o1 != null && o1.equals(o2))
-         return true;
-      
-      return false;
-   }
-   
-   public int hashCode()
-   {
-      int result = 629 * fqn.hashCode();
-
-      if (field != null)
-         result = 37 * result + field.hashCode();
-      
-      return result;
-   }
-   
-   public boolean equals(Object o)
-   {
-      if (o instanceof Referrer)
-         return equals(((Referrer)o).fqn, fqn) && equals(((Referrer)o).field, field);
-      
-      return false;
-   }
-}
\ No newline at end of file

Deleted: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/SerializableObjectHandler.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/SerializableObjectHandler.java	2008-07-16 17:30:08 UTC (rev 6310)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/SerializableObjectHandler.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -1,95 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-
-package org.jboss.cache.pojo.impl;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.jboss.cache.Cache;
-import org.jboss.cache.CacheException;
-import org.jboss.cache.CacheSPI;
-import org.jboss.cache.Fqn;
-
-/**
- * Handle Serializable object cache management.
- *
- * @author Ben Wang
- * @version $Id$
- */
-class SerializableObjectHandler extends AbstractHandler
-{
-   private Cache<Object, Object> cache;
-   private PojoCacheImpl pojoCache;
-   private InternalHelper internal_;
-   private final Log log_ = LogFactory.getLog(SerializableObjectHandler.class);
-
-   public SerializableObjectHandler(PojoCacheImpl cache, InternalHelper internal)
-   {
-      pojoCache = cache;
-      this.cache = pojoCache.getCache();
-      internal_ = internal;
-   }
-   
-   protected Fqn<?> getFqn(Object obj)
-   {
-      // Not supported
-      return null;
-   }
-   
-   @Override
-   protected boolean handles(Class<?> clazz)
-   {
-      return Serializable.class.isAssignableFrom(clazz);
-   }
-
-   @Override
-   protected Object get(Fqn fqn, Class clazz, PojoInstance pojoInstance) throws CacheException
-   {
-      Object obj = internal_.get(fqn, InternalConstant.SERIALIZED);
-      return obj;
-   }
-
-
-   @Override
-   protected void put(Fqn<?> fqn, Fqn<?> referencingFqn, Object obj) throws CacheException
-   {
-      // Note that JBoss Serialization can serialize any type now.
-      if (log_.isDebugEnabled())
-      {
-         log_.debug("put(): obj (" + obj.getClass() + ") is non-advisable but serialize it anyway. "
-                    + "Note that if it is non-serializable we require to use JBoss Serialization.");
-      }
-
-      putIntoCache(fqn, obj);
-   }
-
-   private void putIntoCache(Fqn fqn, Object obj)
-         throws CacheException
-   {
-      Map map = new HashMap();
-
-      // Special optimization here.
-      PojoInstance pojoInstance = new PojoInstance();
-      pojoInstance.set(obj);
-      pojoInstance.setPojoClass(obj.getClass());
-      map.put(PojoInstance.KEY, pojoInstance);
-      // Note that we will only have one key in this fqn.
-      map.put(InternalConstant.SERIALIZED, obj);
-      internal_.put(fqn, map);
-   }
-
-   @Override
-   protected Object remove(Fqn<?> fqn, Fqn<?> referenceingFqn, Object result) throws CacheException
-   {
-      cache.removeNode(fqn);
-      return result;
-   }
-}
\ No newline at end of file

Copied: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/SerializableObjectHandler.java (from rev 6374, pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/SerializableObjectHandler.java)
===================================================================
--- pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/SerializableObjectHandler.java	                        (rev 0)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/impl/SerializableObjectHandler.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -0,0 +1,95 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+package org.jboss.cache.pojo.impl;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.Cache;
+import org.jboss.cache.CacheException;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.pojo.Reference;
+
+/**
+ * Handle Serializable object cache management.
+ *
+ * @author Ben Wang
+ * @version $Id$
+ */
+class SerializableObjectHandler extends AbstractHandler
+{
+   private Cache<Object, Object> cache;
+   private PojoCacheImpl pojoCache;
+   private InternalHelper internal_;
+   private final Log log_ = LogFactory.getLog(SerializableObjectHandler.class);
+
+   public SerializableObjectHandler(PojoCacheImpl cache, InternalHelper internal)
+   {
+      pojoCache = cache;
+      this.cache = pojoCache.getCache();
+      internal_ = internal;
+   }
+
+   protected Fqn<?> getFqn(Object obj)
+   {
+      // Not supported
+      return null;
+   }
+
+   @Override
+   protected boolean handles(Class<?> clazz)
+   {
+      return Serializable.class.isAssignableFrom(clazz);
+   }
+
+   @Override
+   protected Object get(Fqn fqn, Class clazz, PojoInstance pojoInstance) throws CacheException
+   {
+      Object obj = internal_.get(fqn, InternalConstant.SERIALIZED);
+      return obj;
+   }
+
+
+   @Override
+   protected void put(Fqn<?> fqn, Reference reference, Object obj) throws CacheException
+   {
+      // Note that JBoss Serialization can serialize any type now.
+      if (log_.isDebugEnabled())
+      {
+         log_.debug("put(): obj (" + obj.getClass() + ") is non-advisable but serialize it anyway. "
+                    + "Note that if it is non-serializable we require to use JBoss Serialization.");
+      }
+
+      putIntoCache(fqn, obj);
+   }
+
+   private void putIntoCache(Fqn fqn, Object obj)
+         throws CacheException
+   {
+      Map map = new HashMap();
+
+      // Special optimization here.
+      PojoInstance pojoInstance = new PojoInstance();
+      pojoInstance.set(obj);
+      pojoInstance.setPojoClass(obj.getClass());
+      map.put(PojoInstance.KEY, pojoInstance);
+      // Note that we will only have one key in this fqn.
+      map.put(InternalConstant.SERIALIZED, obj);
+      internal_.put(fqn, map);
+   }
+
+   @Override
+   protected Object remove(Fqn<?> fqn, Reference reference, Object result) throws CacheException
+   {
+      cache.removeNode(fqn);
+      return result;
+   }
+}
\ No newline at end of file

Deleted: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/jmx/PojoCacheJmxWrapper.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/jmx/PojoCacheJmxWrapper.java	2008-07-16 17:30:08 UTC (rev 6310)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/jmx/PojoCacheJmxWrapper.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -1,1033 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2006, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.cache.pojo.jmx;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.jboss.cache.CacheException;
-import org.jboss.cache.CacheStatus;
-import org.jboss.cache.config.BuddyReplicationConfig;
-import org.jboss.cache.config.CacheLoaderConfig;
-import org.jboss.cache.config.Configuration;
-import org.jboss.cache.config.ConfigurationException;
-import org.jboss.cache.config.EvictionConfig;
-import org.jboss.cache.config.RuntimeConfig;
-import org.jboss.cache.factories.XmlConfigurationParser;
-import org.jboss.cache.jmx.CacheJmxWrapper;
-import org.jboss.cache.jmx.CacheNotificationListener;
-import org.jboss.cache.pojo.PojoCache;
-import org.jboss.cache.pojo.PojoCacheAlreadyDetachedException;
-import org.jboss.cache.pojo.PojoCacheException;
-import org.jboss.cache.pojo.PojoCacheFactory;
-import org.jboss.cache.pojo.impl.PojoCacheImpl;
-import org.jgroups.Channel;
-import org.jgroups.ChannelFactory;
-import org.jgroups.jmx.JChannelFactoryMBean;
-import org.w3c.dom.Element;
-
-import javax.management.AttributeChangeNotification;
-import javax.management.JMException;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanNotificationInfo;
-import javax.management.MBeanRegistration;
-import javax.management.MBeanServer;
-import javax.management.NotificationEmitter;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.transaction.TransactionManager;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-public class PojoCacheJmxWrapper
-        implements PojoCacheJmxWrapperMBean, MBeanRegistration, NotificationEmitter
-{
-   private Log log = LogFactory.getLog(getClass().getName());
-
-   private boolean registerInterceptors = true;
-   private Configuration config;
-   private MBeanServer server;
-   private String cacheObjectName;
-   private PojoCache pojoCache;
-   private CacheJmxWrapper plainCacheWrapper;
-   private boolean registerPlainCache = true;
-   private boolean plainCacheRegistered;
-   private CacheStatus cacheStatus;
-   private boolean registered;
-   private final Set<NotificationListenerArgs> pendingListeners =
-           new HashSet<NotificationListenerArgs>();
-
-   // Legacy config support
-
-   private Element buddyReplConfig;
-   private Element evictionConfig;
-   private Element cacheLoaderConfig;
-   private Element clusterConfig;
-   private JChannelFactoryMBean multiplexerService;
-
-   /**
-    * Default constructor.
-    */
-   public PojoCacheJmxWrapper()
-   {
-      cacheStatus = CacheStatus.INSTANTIATED;
-   }
-
-   /**
-    * Creates a PojoCacheJmxWrapper that wraps the given PojoCache.
-    *
-    * @param toWrap the cache
-    */
-   public PojoCacheJmxWrapper(PojoCache toWrap)
-   {
-      this();
-      setPojoCache(toWrap);
-   }
-
-   // PojoCacheMBean
-
-   public PojoCache getPojoCache()
-   {
-      return pojoCache;
-   }
-
-   public Configuration getConfiguration()
-   {
-      Configuration cfg = (pojoCache == null ? config : pojoCache.getCache().getConfiguration());
-      if (cfg == null)
-      {
-         cfg = config = new Configuration();
-      }
-      return cfg;
-   }
-
-   public String getInternalLocation(Object pojo) throws PojoCacheAlreadyDetachedException
-   {
-      return pojoCache.getPojoID(pojo);
-   }
-
-   public String getUnderlyingCacheObjectName()
-   {
-      return plainCacheWrapper == null ? null : plainCacheWrapper.getCacheObjectName();
-   }
-
-   public void create() throws PojoCacheException
-   {
-      if (cacheStatus.createAllowed() == false)
-      {
-         if (cacheStatus.needToDestroyFailedCache())
-            destroy();
-         else
-            return;
-      }
-
-      try
-      {
-         cacheStatus = CacheStatus.CREATING;
-
-         if (pojoCache == null)
-         {
-            if (config == null)
-            {
-               throw new ConfigurationException("Must call setConfiguration() " +
-                       "or setPojoCache() before call to create()");
-            }
-
-            constructCache();
-         }
-
-         pojoCache.create();
-
-         registerPlainCache();
-
-         plainCacheWrapper.create();
-
-         cacheStatus = CacheStatus.CREATED;
-      }
-      catch (Throwable t)
-      {
-         handleLifecycleTransitionFailure(t);
-      }
-   }
-
-   public void start() throws PojoCacheException
-   {
-      if (cacheStatus.startAllowed() == false)
-      {
-         if (cacheStatus.needToDestroyFailedCache())
-            destroy();
-         if (cacheStatus.needCreateBeforeStart())
-            create();
-         else
-            return;
-      }
-
-      try
-      {
-         int oldState = getState();
-         cacheStatus = CacheStatus.STARTING;
-         int startingState = getState();
-         sendStateChangeNotification(oldState, startingState, getClass().getSimpleName() + " starting", null);
-
-         pojoCache.start();
-
-         plainCacheWrapper.start();
-         cacheStatus = CacheStatus.STARTED;
-         sendStateChangeNotification(startingState, getState(), getClass().getSimpleName() + " started", null);
-      }
-      catch (Throwable t)
-      {
-         handleLifecycleTransitionFailure(t);
-      }
-   }
-
-   public void stop()
-   {
-      if (cacheStatus.stopAllowed() == false)
-      {
-         return;
-      }
-
-      // Trying to stop() from FAILED is valid, but may not work
-      boolean failed = cacheStatus == CacheStatus.FAILED;
-
-      try
-      {
-         int oldState = getState();
-         cacheStatus = CacheStatus.STOPPING;
-         int stoppingState = getState();
-         sendStateChangeNotification(oldState, stoppingState, getClass().getSimpleName() + " stopping", null);
-
-         cacheStatus = CacheStatus.STOPPING;
-
-         pojoCache.stop();
-
-         plainCacheWrapper.stop();
-         cacheStatus = CacheStatus.STOPPED;
-         sendStateChangeNotification(stoppingState, getState(), getClass().getSimpleName() + " stopped", null);
-      }
-      catch (Throwable t)
-      {
-         if (failed)
-         {
-            log.warn("Attempted to stop() from FAILED state, " +
-                    "but caught exception; try calling destroy()", t);
-         }
-         handleLifecycleTransitionFailure(t);
-      }
-   }
-
-   public void destroy()
-   {
-      if (cacheStatus.destroyAllowed() == false)
-      {
-         if (cacheStatus.needStopBeforeDestroy())
-            stop();
-         else
-            return;
-      }
-
-      try
-      {
-         cacheStatus = CacheStatus.DESTROYING;
-
-         if (pojoCache != null)
-            pojoCache.destroy();
-
-         // The cache is destroyed, so we shouldn't leave it registered
-         // in JMX even if we didn't register it in create()
-         unregisterPlainCache();
-
-         if (plainCacheWrapper != null)
-            plainCacheWrapper.destroy();
-      }
-      finally
-      {
-         // We always proceed to DESTROYED
-         cacheStatus = CacheStatus.DESTROYED;
-      }
-   }
-
-   public CacheStatus getCacheStatus()
-   {
-      return cacheStatus;
-   }
-
-   public int getState()
-   {
-      switch (cacheStatus)
-      {
-         case INSTANTIATED:
-         case CREATING:
-            return registered ? REGISTERED : UNREGISTERED;
-         case CREATED:
-            return CREATED;
-         case STARTING:
-            return STARTING;
-         case STARTED:
-            return STARTED;
-         case STOPPING:
-            return STOPPING;
-         case STOPPED:
-         case DESTROYING:
-            return STOPPED;
-         case DESTROYED:
-            return registered ? DESTROYED : UNREGISTERED;
-         case FAILED:
-         default:
-            return FAILED;
-      }
-   }
-
-   public boolean getRegisterPlainCache()
-   {
-      return registerPlainCache;
-   }
-
-   public void setRegisterPlainCache(boolean registerPlainCache)
-   {
-      this.registerPlainCache = registerPlainCache;
-   }
-
-   public boolean getRegisterInterceptors()
-   {
-      return registerInterceptors;
-   }
-
-   public void setRegisterInterceptors(boolean register)
-   {
-      this.registerInterceptors = register;
-   }
-
-   // ----------------------------------------------------  LegacyConfiguration
-
-   public Element getBuddyReplicationConfig()
-   {
-      return buddyReplConfig;
-   }
-
-   public Element getCacheLoaderConfig()
-   {
-      return cacheLoaderConfig;
-   }
-
-   public Element getCacheLoaderConfiguration()
-   {
-      return getCacheLoaderConfig();
-   }
-
-   public String getCacheMode()
-   {
-      return getConfiguration().getCacheModeString();
-   }
-
-   public String getClusterName()
-   {
-      return getConfiguration().getClusterName();
-   }
-
-   public String getClusterProperties()
-   {
-      return getConfiguration().getClusterConfig();
-   }
-
-   public Element getClusterConfig()
-   {
-      return clusterConfig;
-   }
-
-   public Element getEvictionPolicyConfig()
-   {
-      return evictionConfig;
-   }
-
-   public boolean getExposeManagementStatistics()
-   {
-      return getConfiguration().getExposeManagementStatistics();
-   }
-
-   public boolean getUseInterceptorMbeans()
-   {
-      return getExposeManagementStatistics();
-   }
-
-   public boolean getFetchInMemoryState()
-   {
-      return getConfiguration().isFetchInMemoryState();
-   }
-
-   public long getStateRetrievalTimeout()
-   {
-      return getConfiguration().getStateRetrievalTimeout();
-   }
-
-   @Deprecated
-   public void setInitialStateRetrievalTimeout(long timeout)
-   {
-      setStateRetrievalTimeout(timeout);
-   }
-
-   public String getIsolationLevel()
-   {
-      return getConfiguration().getIsolationLevelString();
-   }
-
-   public long getLockAcquisitionTimeout()
-   {
-      return getConfiguration().getLockAcquisitionTimeout();
-   }
-
-   public JChannelFactoryMBean getMultiplexerService()
-   {
-      return multiplexerService;
-   }
-
-   public String getMultiplexerStack()
-   {
-      return getConfiguration().getMultiplexerStack();
-   }
-
-   public ChannelFactory getMuxChannelFactory()
-   {
-      return getConfiguration().getRuntimeConfig().getMuxChannelFactory();
-   }
-
-   public String getNodeLockingScheme()
-   {
-      return getConfiguration().getNodeLockingSchemeString();
-   }
-
-   public long getReplQueueInterval()
-   {
-      return getConfiguration().getReplQueueInterval();
-   }
-
-   public int getReplQueueMaxElements()
-   {
-      return getConfiguration().getReplQueueMaxElements();
-   }
-
-   public String getReplicationVersion()
-   {
-      return getConfiguration().getReplVersionString();
-   }
-
-   public boolean getSyncCommitPhase()
-   {
-      return getConfiguration().isSyncCommitPhase();
-   }
-
-   public long getSyncReplTimeout()
-   {
-      return getConfiguration().getSyncReplTimeout();
-   }
-
-   public boolean getSyncRollbackPhase()
-   {
-      return getConfiguration().isSyncRollbackPhase();
-   }
-
-   public TransactionManager getTransactionManager()
-   {
-      return getConfiguration().getRuntimeConfig().getTransactionManager();
-   }
-
-   public String getTransactionManagerLookupClass()
-   {
-      return getConfiguration().getTransactionManagerLookupClass();
-   }
-
-   public boolean getUseRegionBasedMarshalling()
-   {
-      return getConfiguration().isUseRegionBasedMarshalling();
-   }
-
-   public boolean getUseReplQueue()
-   {
-      return getConfiguration().isUseReplQueue();
-   }
-
-   public boolean isInactiveOnStartup()
-   {
-      return getConfiguration().isInactiveOnStartup();
-   }
-
-   public void setBuddyReplicationConfig(Element config)
-   {
-      BuddyReplicationConfig brc = null;
-      if (config != null)
-      {
-         brc = XmlConfigurationParser.parseBuddyReplicationConfig(config);
-      }
-      getConfiguration().setBuddyReplicationConfig(brc);
-      this.buddyReplConfig = config;
-   }
-
-   public void setCacheLoaderConfig(Element cache_loader_config)
-   {
-      CacheLoaderConfig clc = null;
-      if (cache_loader_config != null)
-      {
-         clc = XmlConfigurationParser.parseCacheLoaderConfig(cache_loader_config);
-      }
-      getConfiguration().setCacheLoaderConfig(clc);
-      this.cacheLoaderConfig = cache_loader_config;
-   }
-
-   public void setCacheLoaderConfiguration(Element config)
-   {
-      log.warn("MBean attribute 'CacheLoaderConfiguration' is deprecated; " +
-              "use 'CacheLoaderConfig'");
-      setCacheLoaderConfig(config);
-   }
-
-   public void setCacheMode(String mode) throws Exception
-   {
-      getConfiguration().setCacheModeString(mode);
-   }
-
-   public void setClusterConfig(Element config)
-   {
-      String props = null;
-      if (config != null)
-      {
-         props = XmlConfigurationParser.parseClusterConfigXml(config);
-      }
-      getConfiguration().setClusterConfig(props);
-      this.clusterConfig = config;
-   }
-
-   @Deprecated
-   public long getInitialStateRetrievalTimeout()
-   {
-      return getStateRetrievalTimeout();
-   }
-
-   public void setClusterName(String name)
-   {
-      getConfiguration().setClusterName(name);
-   }
-
-   public void setClusterProperties(String cluster_props)
-   {
-      getConfiguration().setClusterConfig(cluster_props);
-   }
-
-   public void setEvictionPolicyConfig(Element config)
-   {
-      EvictionConfig ec = null;
-      if (config != null)
-      {
-         ec = XmlConfigurationParser.parseEvictionConfig(config);
-      }
-      getConfiguration().setEvictionConfig(ec);
-      this.evictionConfig = config;
-   }
-
-   public void setExposeManagementStatistics(boolean expose)
-   {
-      getConfiguration().setExposeManagementStatistics(expose);
-   }
-
-   public void setUseInterceptorMbeans(boolean use)
-   {
-      log.warn("MBean attribute 'UseInterceptorMbeans' is deprecated; " +
-              "use 'ExposeManagementStatistics'");
-      setExposeManagementStatistics(use);
-   }
-
-   public void setFetchInMemoryState(boolean flag)
-   {
-      getConfiguration().setFetchInMemoryState(flag);
-   }
-
-   public void setInactiveOnStartup(boolean inactiveOnStartup)
-   {
-      getConfiguration().setInactiveOnStartup(inactiveOnStartup);
-   }
-
-   public void setStateRetrievalTimeout(long timeout)
-   {
-      getConfiguration().setStateRetrievalTimeout(timeout);
-   }
-
-   public void setIsolationLevel(String level)
-   {
-      getConfiguration().setIsolationLevelString(level);
-   }
-
-   public void setLockAcquisitionTimeout(long timeout)
-   {
-      getConfiguration().setLockAcquisitionTimeout(timeout);
-   }
-
-   public void setMultiplexerService(JChannelFactoryMBean muxService)
-   {
-      this.multiplexerService = muxService;
-   }
-
-   public void setMultiplexerStack(String stackName)
-   {
-      getConfiguration().setMultiplexerStack(stackName);
-   }
-
-   public void setMuxChannelFactory(ChannelFactory factory)
-   {
-      getConfiguration().getRuntimeConfig().setMuxChannelFactory(factory);
-   }
-
-   public void setNodeLockingScheme(String nodeLockingScheme)
-   {
-      getConfiguration().setNodeLockingSchemeString(nodeLockingScheme);
-   }
-
-   public void setReplQueueInterval(long interval)
-   {
-      getConfiguration().setReplQueueInterval(interval);
-   }
-
-   public void setReplQueueMaxElements(int max_elements)
-   {
-      getConfiguration().setReplQueueMaxElements(max_elements);
-   }
-
-   public void setReplicationVersion(String version)
-   {
-      getConfiguration().setReplVersionString(version);
-   }
-
-   public void setSyncCommitPhase(boolean sync_commit_phase)
-   {
-      getConfiguration().setSyncCommitPhase(sync_commit_phase);
-   }
-
-   public void setSyncReplTimeout(long timeout)
-   {
-      getConfiguration().setSyncReplTimeout(timeout);
-   }
-
-   public void setSyncRollbackPhase(boolean sync_rollback_phase)
-   {
-      getConfiguration().setSyncRollbackPhase(sync_rollback_phase);
-   }
-
-   public void setTransactionManager(TransactionManager manager)
-   {
-      getConfiguration().getRuntimeConfig().setTransactionManager(manager);
-   }
-
-   public void setTransactionManagerLookupClass(String cl) throws Exception
-   {
-      getConfiguration().setTransactionManagerLookupClass(cl);
-   }
-
-   public void setUseRegionBasedMarshalling(boolean isTrue)
-   {
-      getConfiguration().setUseRegionBasedMarshalling(isTrue);
-   }
-
-   public void setUseReplQueue(boolean flag)
-   {
-      getConfiguration().setUseReplQueue(flag);
-   }
-
-   // ------------------------------------------------------  MBeanRegistration
-
-   /**
-    * Caches the provided <code>server</code> and <code>objName</code>.
-    */
-   public ObjectName preRegister(MBeanServer server, ObjectName objName)
-           throws Exception
-   {
-      this.server = server;
-
-      if (cacheObjectName == null)
-      {
-         cacheObjectName = objName.getCanonicalName();
-      }
-
-      if (plainCacheWrapper != null)
-         plainCacheWrapper.setNotificationServiceName(cacheObjectName);
-
-      return new ObjectName(cacheObjectName);
-   }
-
-   /**
-    * Registers the CacheJmxWrapperMBean,
-    * if {@link #getRegisterPlainCache()} is <code>true</code>.
-    */
-   public void postRegister(Boolean registrationDone)
-   {
-      if (Boolean.TRUE.equals(registrationDone) && registerPlainCache)
-      {
-         log.debug("Registered in JMX under " + cacheObjectName);
-
-         if (plainCacheWrapper != null)
-         {
-            try
-            {
-               registerPlainCache();
-            }
-            catch (Exception e)
-            {
-               log.error("Caught exception registering plain cache with JMX", e);
-            }
-         }
-
-         registered = true;
-      }
-   }
-
-   /**
-    * No-op.
-    */
-   public void preDeregister() throws Exception
-   {
-   }
-
-   /**
-    * Unregisters the CacheJmxWrapper, if {@link #getRegisterPlainCache()} is
-    * <code>true</code>.
-    */
-   public void postDeregister()
-   {
-      if (plainCacheWrapper != null)
-      {
-         unregisterPlainCache();
-      }
-
-      registered = false;
-   }
-
-   // ----------------------------------------------------  NotificationEmitter 
-
-   public void removeNotificationListener(NotificationListener listener,
-                                          NotificationFilter filter,
-                                          Object handback)
-           throws ListenerNotFoundException
-   {
-      synchronized (pendingListeners)
-      {
-         boolean found = pendingListeners.remove(new NotificationListenerArgs(listener, filter, handback));
-
-         if (plainCacheWrapper != null)
-         {
-            plainCacheWrapper.removeNotificationListener(listener, filter, handback);
-         }
-         else if (!found)
-         {
-            throw new ListenerNotFoundException();
-         }
-      }
-   }
-
-   public void addNotificationListener(NotificationListener listener,
-                                       NotificationFilter filter,
-                                       Object handback)
-           throws IllegalArgumentException
-   {
-      synchronized (pendingListeners)
-      {
-         if (plainCacheWrapper != null)
-         {
-            plainCacheWrapper.addNotificationListener(listener, filter, handback);
-         }
-         else
-         {
-            // Add it for addition to the plainCacheWrapper when it's created
-            pendingListeners.add(new NotificationListenerArgs(listener, filter, handback));
-         }
-      }
-
-   }
-
-   public MBeanNotificationInfo[] getNotificationInfo()
-   {
-      return CacheNotificationListener.getNotificationInfo();
-   }
-
-   public void removeNotificationListener(NotificationListener listener)
-           throws ListenerNotFoundException
-   {
-      synchronized (pendingListeners)
-      {
-         boolean found = false;
-         for (Iterator<NotificationListenerArgs> iter = pendingListeners.iterator();
-              iter.hasNext();)
-         {
-            NotificationListenerArgs args = iter.next();
-            if (safeEquals(listener, args.listener))
-            {
-               found = true;
-               iter.remove();
-            }
-         }
-
-         if (plainCacheWrapper != null)
-         {
-            plainCacheWrapper.removeNotificationListener(listener);
-         }
-         else if (!found)
-         {
-            throw new ListenerNotFoundException();
-         }
-
-      }
-   }
-
-   // ---------------------------------------------------------  Public methods
-
-   public MBeanServer getMBeanServer()
-   {
-      return server;
-   }
-
-   /**
-    * Sets the configuration that the underlying cache should use.
-    *
-    * @param config the configuration
-    */
-   public void setConfiguration(Configuration config)
-   {
-      this.config = config;
-   }
-
-   public void setPojoCache(PojoCache cache)
-   {
-      if (cacheStatus != CacheStatus.INSTANTIATED
-              && cacheStatus != CacheStatus.DESTROYED)
-         throw new IllegalStateException("Cannot set underlying cache after call to create()");
-
-      this.pojoCache = cache;
-      if (pojoCache == null)
-      {
-         this.config = null;
-         this.plainCacheWrapper = null;
-      }
-      else
-      {
-         this.config = cache.getCache().getConfiguration();
-         this.plainCacheWrapper = buildPlainCacheWrapper(pojoCache);
-      }
-   }
-
-   // ---------------------------------------------------------------  Private methods
-
-   private void constructCache() throws ConfigurationException
-   {
-      pojoCache = (PojoCacheImpl) PojoCacheFactory.createCache(config, false);
-
-      plainCacheWrapper = buildPlainCacheWrapper(pojoCache);
-      if (multiplexerService != null)
-      {
-         injectMuxChannel();
-      }
-   }
-
-   private CacheJmxWrapper buildPlainCacheWrapper(PojoCache pojoCache)
-   {
-      CacheJmxWrapper plainCache = new CacheJmxWrapper();
-      plainCache.setRegisterInterceptors(getRegisterInterceptors());
-      plainCache.setCache(pojoCache.getCache());
-      // It shouldn't send out lifecycle state change notifications for itself; 
-      // we do it
-      plainCache.setDisableStateChangeNotifications(true);
-
-      if (server != null)
-      {
-         plainCache.setNotificationServiceName(cacheObjectName);
-      }
-
-      // Add any NotificationListeners we registered before creating
-      // the CacheJmxWrapper
-      synchronized (pendingListeners)
-      {
-         for (NotificationListenerArgs args : pendingListeners)
-         {
-            plainCache.addNotificationListener(args.listener, args.filter, args.handback);
-         }
-      }
-      return plainCache;
-   }
-
-   private boolean registerPlainCache() throws CacheException
-   {
-      if (registerPlainCache && !plainCacheRegistered && server != null)
-      {
-         try
-         {
-            ObjectName ourName = new ObjectName(cacheObjectName);
-            ObjectName plainName = JmxUtil.getPlainCacheObjectName(ourName);
-            log.debug("Registering plain cache under name " + plainName.getCanonicalName());
-            org.jboss.cache.jmx.JmxUtil.registerCacheMBean(server, plainCacheWrapper, plainName.getCanonicalName());
-            plainCacheRegistered = true;
-            return true;
-         }
-         catch (JMException e)
-         {
-            throw new CacheException("Failed to register plain cache", e);
-         }
-      }
-
-      return false;
-   }
-
-   private void unregisterPlainCache()
-   {
-      if (registerPlainCache && plainCacheRegistered && server != null)
-      {
-         log.debug("Unregistering plain cache");
-         try
-         {
-            org.jboss.cache.jmx.JmxUtil.unregisterCacheMBean(server, plainCacheWrapper.getCacheObjectName());
-         }
-         catch (Exception e)
-         {
-            log.error("Could not unregister plain cache", e);
-         }
-         plainCacheRegistered = false;
-      }
-   }
-
-   private void injectMuxChannel() throws CacheException
-   {
-      Configuration cfg = getConfiguration();
-      RuntimeConfig rtcfg = cfg.getRuntimeConfig();
-
-      // Only inject if there isn't already a channel or factory
-      if (rtcfg.getMuxChannelFactory() != null && rtcfg.getChannel() != null)
-      {
-         Channel ch;
-         try
-         {
-            ch = multiplexerService.createMultiplexerChannel(cfg.getMultiplexerStack(), cfg.getClusterName());
-         }
-         catch (Exception e)
-         {
-            throw new CacheException("Exception creating multiplexed channel", e);
-         }
-         rtcfg.setChannel(ch);
-      }
-
-   }
-
-   /**
-    * Helper for sending out state change notifications
-    */
-   private void sendStateChangeNotification(int oldState, int newState, String msg, Throwable t)
-   {
-      if (plainCacheWrapper != null)
-      {
-         long now = System.currentTimeMillis();
-   
-         AttributeChangeNotification stateChangeNotification = new AttributeChangeNotification(
-                 this,
-                 plainCacheWrapper.getNextNotificationSequenceNumber(), now, msg,
-                 "State", "java.lang.Integer",
-                 new Integer(oldState), new Integer(newState)
-         );
-         stateChangeNotification.setUserData(t);
-   
-         plainCacheWrapper.sendNotification(stateChangeNotification);
-      }
-   }
-
-   /**
-    * Sets the cacheStatus to FAILED and rethrows the problem as one
-    * of the declared types. Converts any non-RuntimeException Exception
-    * to CacheException.
-    *
-    * @param t
-    * @throws PojoCacheException
-    * @throws RuntimeException
-    * @throws Error
-    */
-   private void handleLifecycleTransitionFailure(Throwable t)
-           throws PojoCacheException, RuntimeException, Error
-   {
-      int oldState = getState();
-      cacheStatus = CacheStatus.FAILED;
-      sendStateChangeNotification(oldState, getState(), getClass().getSimpleName() + " failed", t);
-
-      if (t instanceof PojoCacheException)
-         throw (PojoCacheException) t;
-      if (t instanceof CacheException)
-         throw (CacheException) t;
-      else if (t instanceof RuntimeException)
-         throw (RuntimeException) t;
-      else if (t instanceof Error)
-         throw (Error) t;
-      else
-         throw new PojoCacheException(t);
-   }
-
-   private static boolean safeEquals(Object us, Object them)
-   {
-      return (us == null ? them == null : us.equals(them));
-   }
-
-   private static class NotificationListenerArgs
-   {
-      NotificationListener listener;
-      NotificationFilter filter;
-      Object handback;
-
-      NotificationListenerArgs(NotificationListener listener,
-                               NotificationFilter filter,
-                               Object handback)
-      {
-         this.listener = listener;
-         this.filter = filter;
-         this.handback = handback;
-      }
-
-      @Override
-      public boolean equals(Object obj)
-      {
-         if (this == obj) return true;
-
-         if (obj instanceof NotificationListenerArgs)
-         {
-            NotificationListenerArgs other = (NotificationListenerArgs) obj;
-            if (safeEquals(listener, other.listener)
-                    && safeEquals(filter, other.filter)
-                    && safeEquals(handback, other.handback))
-            {
-               return true;
-            }
-         }
-         return false;
-      }
-
-      @Override
-      public int hashCode()
-      {
-         int result = 17;
-         result = 29 * result + (listener != null ? listener.hashCode() : 0);
-         result = 29 * result + (filter != null ? filter.hashCode() : 0);
-         result = 29 * result + (handback != null ? handback.hashCode() : 0);
-         return result;
-      }
-   }
-
-}

Copied: pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/jmx/PojoCacheJmxWrapper.java (from rev 6374, pojo/trunk/src/main/java/org/jboss/cache/pojo/jmx/PojoCacheJmxWrapper.java)
===================================================================
--- pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/jmx/PojoCacheJmxWrapper.java	                        (rev 0)
+++ pojo/tags/2.2.0.CR7/src/main/java/org/jboss/cache/pojo/jmx/PojoCacheJmxWrapper.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -0,0 +1,1033 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.cache.pojo.jmx;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.CacheException;
+import org.jboss.cache.CacheStatus;
+import org.jboss.cache.config.BuddyReplicationConfig;
+import org.jboss.cache.config.CacheLoaderConfig;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.config.ConfigurationException;
+import org.jboss.cache.config.EvictionConfig;
+import org.jboss.cache.config.RuntimeConfig;
+import org.jboss.cache.factories.XmlConfigurationParser;
+import org.jboss.cache.jmx.CacheJmxWrapper;
+import org.jboss.cache.jmx.CacheNotificationListener;
+import org.jboss.cache.pojo.PojoCache;
+import org.jboss.cache.pojo.PojoCacheAlreadyDetachedException;
+import org.jboss.cache.pojo.PojoCacheException;
+import org.jboss.cache.pojo.PojoCacheFactory;
+import org.jboss.cache.pojo.impl.PojoCacheImpl;
+import org.jgroups.Channel;
+import org.jgroups.ChannelFactory;
+import org.jgroups.jmx.JChannelFactoryMBean;
+import org.w3c.dom.Element;
+
+import javax.management.AttributeChangeNotification;
+import javax.management.JMException;
+import javax.management.ListenerNotFoundException;
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanRegistration;
+import javax.management.MBeanServer;
+import javax.management.NotificationEmitter;
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.transaction.TransactionManager;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+public class PojoCacheJmxWrapper
+        implements PojoCacheJmxWrapperMBean, MBeanRegistration, NotificationEmitter
+{
+   private Log log = LogFactory.getLog(getClass().getName());
+
+   private boolean registerInterceptors = true;
+   private Configuration config;
+   private MBeanServer server;
+   private String cacheObjectName;
+   private PojoCache pojoCache;
+   private CacheJmxWrapper plainCacheWrapper;
+   private boolean registerPlainCache = true;
+   private boolean plainCacheRegistered;
+   private CacheStatus cacheStatus;
+   private boolean registered;
+   private final Set<NotificationListenerArgs> pendingListeners =
+           new HashSet<NotificationListenerArgs>();
+
+   // Legacy config support
+
+   private Element buddyReplConfig;
+   private Element evictionConfig;
+   private Element cacheLoaderConfig;
+   private Element clusterConfig;
+   private JChannelFactoryMBean multiplexerService;
+
+   /**
+    * Default constructor.
+    */
+   public PojoCacheJmxWrapper()
+   {
+      cacheStatus = CacheStatus.INSTANTIATED;
+   }
+
+   /**
+    * Creates a PojoCacheJmxWrapper that wraps the given PojoCache.
+    *
+    * @param toWrap the cache
+    */
+   public PojoCacheJmxWrapper(PojoCache toWrap)
+   {
+      this();
+      setPojoCache(toWrap);
+   }
+
+   // PojoCacheMBean
+
+   public PojoCache getPojoCache()
+   {
+      return pojoCache;
+   }
+
+   public Configuration getConfiguration()
+   {
+      Configuration cfg = (pojoCache == null ? config : pojoCache.getCache().getConfiguration());
+      if (cfg == null)
+      {
+         cfg = config = new Configuration();
+      }
+      return cfg;
+   }
+
+   public String getInternalLocation(Object pojo) throws PojoCacheAlreadyDetachedException
+   {
+      return pojoCache.getInternalFqn(pojo).toString();
+   }
+
+   public String getUnderlyingCacheObjectName()
+   {
+      return plainCacheWrapper == null ? null : plainCacheWrapper.getCacheObjectName();
+   }
+
+   public void create() throws PojoCacheException
+   {
+      if (cacheStatus.createAllowed() == false)
+      {
+         if (cacheStatus.needToDestroyFailedCache())
+            destroy();
+         else
+            return;
+      }
+
+      try
+      {
+         cacheStatus = CacheStatus.CREATING;
+
+         if (pojoCache == null)
+         {
+            if (config == null)
+            {
+               throw new ConfigurationException("Must call setConfiguration() " +
+                       "or setPojoCache() before call to create()");
+            }
+
+            constructCache();
+         }
+
+         pojoCache.create();
+
+         registerPlainCache();
+
+         plainCacheWrapper.create();
+
+         cacheStatus = CacheStatus.CREATED;
+      }
+      catch (Throwable t)
+      {
+         handleLifecycleTransitionFailure(t);
+      }
+   }
+
+   public void start() throws PojoCacheException
+   {
+      if (cacheStatus.startAllowed() == false)
+      {
+         if (cacheStatus.needToDestroyFailedCache())
+            destroy();
+         if (cacheStatus.needCreateBeforeStart())
+            create();
+         else
+            return;
+      }
+
+      try
+      {
+         int oldState = getState();
+         cacheStatus = CacheStatus.STARTING;
+         int startingState = getState();
+         sendStateChangeNotification(oldState, startingState, getClass().getSimpleName() + " starting", null);
+
+         pojoCache.start();
+
+         plainCacheWrapper.start();
+         cacheStatus = CacheStatus.STARTED;
+         sendStateChangeNotification(startingState, getState(), getClass().getSimpleName() + " started", null);
+      }
+      catch (Throwable t)
+      {
+         handleLifecycleTransitionFailure(t);
+      }
+   }
+
+   public void stop()
+   {
+      if (cacheStatus.stopAllowed() == false)
+      {
+         return;
+      }
+
+      // Trying to stop() from FAILED is valid, but may not work
+      boolean failed = cacheStatus == CacheStatus.FAILED;
+
+      try
+      {
+         int oldState = getState();
+         cacheStatus = CacheStatus.STOPPING;
+         int stoppingState = getState();
+         sendStateChangeNotification(oldState, stoppingState, getClass().getSimpleName() + " stopping", null);
+
+         cacheStatus = CacheStatus.STOPPING;
+
+         pojoCache.stop();
+
+         plainCacheWrapper.stop();
+         cacheStatus = CacheStatus.STOPPED;
+         sendStateChangeNotification(stoppingState, getState(), getClass().getSimpleName() + " stopped", null);
+      }
+      catch (Throwable t)
+      {
+         if (failed)
+         {
+            log.warn("Attempted to stop() from FAILED state, " +
+                    "but caught exception; try calling destroy()", t);
+         }
+         handleLifecycleTransitionFailure(t);
+      }
+   }
+
+   public void destroy()
+   {
+      if (cacheStatus.destroyAllowed() == false)
+      {
+         if (cacheStatus.needStopBeforeDestroy())
+            stop();
+         else
+            return;
+      }
+
+      try
+      {
+         cacheStatus = CacheStatus.DESTROYING;
+
+         if (pojoCache != null)
+            pojoCache.destroy();
+
+         // The cache is destroyed, so we shouldn't leave it registered
+         // in JMX even if we didn't register it in create()
+         unregisterPlainCache();
+
+         if (plainCacheWrapper != null)
+            plainCacheWrapper.destroy();
+      }
+      finally
+      {
+         // We always proceed to DESTROYED
+         cacheStatus = CacheStatus.DESTROYED;
+      }
+   }
+
+   public CacheStatus getCacheStatus()
+   {
+      return cacheStatus;
+   }
+
+   public int getState()
+   {
+      switch (cacheStatus)
+      {
+         case INSTANTIATED:
+         case CREATING:
+            return registered ? REGISTERED : UNREGISTERED;
+         case CREATED:
+            return CREATED;
+         case STARTING:
+            return STARTING;
+         case STARTED:
+            return STARTED;
+         case STOPPING:
+            return STOPPING;
+         case STOPPED:
+         case DESTROYING:
+            return STOPPED;
+         case DESTROYED:
+            return registered ? DESTROYED : UNREGISTERED;
+         case FAILED:
+         default:
+            return FAILED;
+      }
+   }
+
+   public boolean getRegisterPlainCache()
+   {
+      return registerPlainCache;
+   }
+
+   public void setRegisterPlainCache(boolean registerPlainCache)
+   {
+      this.registerPlainCache = registerPlainCache;
+   }
+
+   public boolean getRegisterInterceptors()
+   {
+      return registerInterceptors;
+   }
+
+   public void setRegisterInterceptors(boolean register)
+   {
+      this.registerInterceptors = register;
+   }
+
+   // ----------------------------------------------------  LegacyConfiguration
+
+   public Element getBuddyReplicationConfig()
+   {
+      return buddyReplConfig;
+   }
+
+   public Element getCacheLoaderConfig()
+   {
+      return cacheLoaderConfig;
+   }
+
+   public Element getCacheLoaderConfiguration()
+   {
+      return getCacheLoaderConfig();
+   }
+
+   public String getCacheMode()
+   {
+      return getConfiguration().getCacheModeString();
+   }
+
+   public String getClusterName()
+   {
+      return getConfiguration().getClusterName();
+   }
+
+   public String getClusterProperties()
+   {
+      return getConfiguration().getClusterConfig();
+   }
+
+   public Element getClusterConfig()
+   {
+      return clusterConfig;
+   }
+
+   public Element getEvictionPolicyConfig()
+   {
+      return evictionConfig;
+   }
+
+   public boolean getExposeManagementStatistics()
+   {
+      return getConfiguration().getExposeManagementStatistics();
+   }
+
+   public boolean getUseInterceptorMbeans()
+   {
+      return getExposeManagementStatistics();
+   }
+
+   public boolean getFetchInMemoryState()
+   {
+      return getConfiguration().isFetchInMemoryState();
+   }
+
+   public long getStateRetrievalTimeout()
+   {
+      return getConfiguration().getStateRetrievalTimeout();
+   }
+
+   @Deprecated
+   public void setInitialStateRetrievalTimeout(long timeout)
+   {
+      setStateRetrievalTimeout(timeout);
+   }
+
+   public String getIsolationLevel()
+   {
+      return getConfiguration().getIsolationLevelString();
+   }
+
+   public long getLockAcquisitionTimeout()
+   {
+      return getConfiguration().getLockAcquisitionTimeout();
+   }
+
+   public JChannelFactoryMBean getMultiplexerService()
+   {
+      return multiplexerService;
+   }
+
+   public String getMultiplexerStack()
+   {
+      return getConfiguration().getMultiplexerStack();
+   }
+
+   public ChannelFactory getMuxChannelFactory()
+   {
+      return getConfiguration().getRuntimeConfig().getMuxChannelFactory();
+   }
+
+   public String getNodeLockingScheme()
+   {
+      return getConfiguration().getNodeLockingSchemeString();
+   }
+
+   public long getReplQueueInterval()
+   {
+      return getConfiguration().getReplQueueInterval();
+   }
+
+   public int getReplQueueMaxElements()
+   {
+      return getConfiguration().getReplQueueMaxElements();
+   }
+
+   public String getReplicationVersion()
+   {
+      return getConfiguration().getReplVersionString();
+   }
+
+   public boolean getSyncCommitPhase()
+   {
+      return getConfiguration().isSyncCommitPhase();
+   }
+
+   public long getSyncReplTimeout()
+   {
+      return getConfiguration().getSyncReplTimeout();
+   }
+
+   public boolean getSyncRollbackPhase()
+   {
+      return getConfiguration().isSyncRollbackPhase();
+   }
+
+   public TransactionManager getTransactionManager()
+   {
+      return getConfiguration().getRuntimeConfig().getTransactionManager();
+   }
+
+   public String getTransactionManagerLookupClass()
+   {
+      return getConfiguration().getTransactionManagerLookupClass();
+   }
+
+   public boolean getUseRegionBasedMarshalling()
+   {
+      return getConfiguration().isUseRegionBasedMarshalling();
+   }
+
+   public boolean getUseReplQueue()
+   {
+      return getConfiguration().isUseReplQueue();
+   }
+
+   public boolean isInactiveOnStartup()
+   {
+      return getConfiguration().isInactiveOnStartup();
+   }
+
+   public void setBuddyReplicationConfig(Element config)
+   {
+      BuddyReplicationConfig brc = null;
+      if (config != null)
+      {
+         brc = XmlConfigurationParser.parseBuddyReplicationConfig(config);
+      }
+      getConfiguration().setBuddyReplicationConfig(brc);
+      this.buddyReplConfig = config;
+   }
+
+   public void setCacheLoaderConfig(Element cache_loader_config)
+   {
+      CacheLoaderConfig clc = null;
+      if (cache_loader_config != null)
+      {
+         clc = XmlConfigurationParser.parseCacheLoaderConfig(cache_loader_config);
+      }
+      getConfiguration().setCacheLoaderConfig(clc);
+      this.cacheLoaderConfig = cache_loader_config;
+   }
+
+   public void setCacheLoaderConfiguration(Element config)
+   {
+      log.warn("MBean attribute 'CacheLoaderConfiguration' is deprecated; " +
+              "use 'CacheLoaderConfig'");
+      setCacheLoaderConfig(config);
+   }
+
+   public void setCacheMode(String mode) throws Exception
+   {
+      getConfiguration().setCacheModeString(mode);
+   }
+
+   public void setClusterConfig(Element config)
+   {
+      String props = null;
+      if (config != null)
+      {
+         props = XmlConfigurationParser.parseClusterConfigXml(config);
+      }
+      getConfiguration().setClusterConfig(props);
+      this.clusterConfig = config;
+   }
+
+   @Deprecated
+   public long getInitialStateRetrievalTimeout()
+   {
+      return getStateRetrievalTimeout();
+   }
+
+   public void setClusterName(String name)
+   {
+      getConfiguration().setClusterName(name);
+   }
+
+   public void setClusterProperties(String cluster_props)
+   {
+      getConfiguration().setClusterConfig(cluster_props);
+   }
+
+   public void setEvictionPolicyConfig(Element config)
+   {
+      EvictionConfig ec = null;
+      if (config != null)
+      {
+         ec = XmlConfigurationParser.parseEvictionConfig(config);
+      }
+      getConfiguration().setEvictionConfig(ec);
+      this.evictionConfig = config;
+   }
+
+   public void setExposeManagementStatistics(boolean expose)
+   {
+      getConfiguration().setExposeManagementStatistics(expose);
+   }
+
+   public void setUseInterceptorMbeans(boolean use)
+   {
+      log.warn("MBean attribute 'UseInterceptorMbeans' is deprecated; " +
+              "use 'ExposeManagementStatistics'");
+      setExposeManagementStatistics(use);
+   }
+
+   public void setFetchInMemoryState(boolean flag)
+   {
+      getConfiguration().setFetchInMemoryState(flag);
+   }
+
+   public void setInactiveOnStartup(boolean inactiveOnStartup)
+   {
+      getConfiguration().setInactiveOnStartup(inactiveOnStartup);
+   }
+
+   public void setStateRetrievalTimeout(long timeout)
+   {
+      getConfiguration().setStateRetrievalTimeout(timeout);
+   }
+
+   public void setIsolationLevel(String level)
+   {
+      getConfiguration().setIsolationLevelString(level);
+   }
+
+   public void setLockAcquisitionTimeout(long timeout)
+   {
+      getConfiguration().setLockAcquisitionTimeout(timeout);
+   }
+
+   public void setMultiplexerService(JChannelFactoryMBean muxService)
+   {
+      this.multiplexerService = muxService;
+   }
+
+   public void setMultiplexerStack(String stackName)
+   {
+      getConfiguration().setMultiplexerStack(stackName);
+   }
+
+   public void setMuxChannelFactory(ChannelFactory factory)
+   {
+      getConfiguration().getRuntimeConfig().setMuxChannelFactory(factory);
+   }
+
+   public void setNodeLockingScheme(String nodeLockingScheme)
+   {
+      getConfiguration().setNodeLockingSchemeString(nodeLockingScheme);
+   }
+
+   public void setReplQueueInterval(long interval)
+   {
+      getConfiguration().setReplQueueInterval(interval);
+   }
+
+   public void setReplQueueMaxElements(int max_elements)
+   {
+      getConfiguration().setReplQueueMaxElements(max_elements);
+   }
+
+   public void setReplicationVersion(String version)
+   {
+      getConfiguration().setReplVersionString(version);
+   }
+
+   public void setSyncCommitPhase(boolean sync_commit_phase)
+   {
+      getConfiguration().setSyncCommitPhase(sync_commit_phase);
+   }
+
+   public void setSyncReplTimeout(long timeout)
+   {
+      getConfiguration().setSyncReplTimeout(timeout);
+   }
+
+   public void setSyncRollbackPhase(boolean sync_rollback_phase)
+   {
+      getConfiguration().setSyncRollbackPhase(sync_rollback_phase);
+   }
+
+   public void setTransactionManager(TransactionManager manager)
+   {
+      getConfiguration().getRuntimeConfig().setTransactionManager(manager);
+   }
+
+   public void setTransactionManagerLookupClass(String cl) throws Exception
+   {
+      getConfiguration().setTransactionManagerLookupClass(cl);
+   }
+
+   public void setUseRegionBasedMarshalling(boolean isTrue)
+   {
+      getConfiguration().setUseRegionBasedMarshalling(isTrue);
+   }
+
+   public void setUseReplQueue(boolean flag)
+   {
+      getConfiguration().setUseReplQueue(flag);
+   }
+
+   // ------------------------------------------------------  MBeanRegistration
+
+   /**
+    * Caches the provided <code>server</code> and <code>objName</code>.
+    */
+   public ObjectName preRegister(MBeanServer server, ObjectName objName)
+           throws Exception
+   {
+      this.server = server;
+
+      if (cacheObjectName == null)
+      {
+         cacheObjectName = objName.getCanonicalName();
+      }
+
+      if (plainCacheWrapper != null)
+         plainCacheWrapper.setNotificationServiceName(cacheObjectName);
+
+      return new ObjectName(cacheObjectName);
+   }
+
+   /**
+    * Registers the CacheJmxWrapperMBean,
+    * if {@link #getRegisterPlainCache()} is <code>true</code>.
+    */
+   public void postRegister(Boolean registrationDone)
+   {
+      if (Boolean.TRUE.equals(registrationDone) && registerPlainCache)
+      {
+         log.debug("Registered in JMX under " + cacheObjectName);
+
+         if (plainCacheWrapper != null)
+         {
+            try
+            {
+               registerPlainCache();
+            }
+            catch (Exception e)
+            {
+               log.error("Caught exception registering plain cache with JMX", e);
+            }
+         }
+
+         registered = true;
+      }
+   }
+
+   /**
+    * No-op.
+    */
+   public void preDeregister() throws Exception
+   {
+   }
+
+   /**
+    * Unregisters the CacheJmxWrapper, if {@link #getRegisterPlainCache()} is
+    * <code>true</code>.
+    */
+   public void postDeregister()
+   {
+      if (plainCacheWrapper != null)
+      {
+         unregisterPlainCache();
+      }
+
+      registered = false;
+   }
+
+   // ----------------------------------------------------  NotificationEmitter 
+
+   public void removeNotificationListener(NotificationListener listener,
+                                          NotificationFilter filter,
+                                          Object handback)
+           throws ListenerNotFoundException
+   {
+      synchronized (pendingListeners)
+      {
+         boolean found = pendingListeners.remove(new NotificationListenerArgs(listener, filter, handback));
+
+         if (plainCacheWrapper != null)
+         {
+            plainCacheWrapper.removeNotificationListener(listener, filter, handback);
+         }
+         else if (!found)
+         {
+            throw new ListenerNotFoundException();
+         }
+      }
+   }
+
+   public void addNotificationListener(NotificationListener listener,
+                                       NotificationFilter filter,
+                                       Object handback)
+           throws IllegalArgumentException
+   {
+      synchronized (pendingListeners)
+      {
+         if (plainCacheWrapper != null)
+         {
+            plainCacheWrapper.addNotificationListener(listener, filter, handback);
+         }
+         else
+         {
+            // Add it for addition to the plainCacheWrapper when it's created
+            pendingListeners.add(new NotificationListenerArgs(listener, filter, handback));
+         }
+      }
+
+   }
+
+   public MBeanNotificationInfo[] getNotificationInfo()
+   {
+      return CacheNotificationListener.getNotificationInfo();
+   }
+
+   public void removeNotificationListener(NotificationListener listener)
+           throws ListenerNotFoundException
+   {
+      synchronized (pendingListeners)
+      {
+         boolean found = false;
+         for (Iterator<NotificationListenerArgs> iter = pendingListeners.iterator();
+              iter.hasNext();)
+         {
+            NotificationListenerArgs args = iter.next();
+            if (safeEquals(listener, args.listener))
+            {
+               found = true;
+               iter.remove();
+            }
+         }
+
+         if (plainCacheWrapper != null)
+         {
+            plainCacheWrapper.removeNotificationListener(listener);
+         }
+         else if (!found)
+         {
+            throw new ListenerNotFoundException();
+         }
+
+      }
+   }
+
+   // ---------------------------------------------------------  Public methods
+
+   public MBeanServer getMBeanServer()
+   {
+      return server;
+   }
+
+   /**
+    * Sets the configuration that the underlying cache should use.
+    *
+    * @param config the configuration
+    */
+   public void setConfiguration(Configuration config)
+   {
+      this.config = config;
+   }
+
+   public void setPojoCache(PojoCache cache)
+   {
+      if (cacheStatus != CacheStatus.INSTANTIATED
+              && cacheStatus != CacheStatus.DESTROYED)
+         throw new IllegalStateException("Cannot set underlying cache after call to create()");
+
+      this.pojoCache = cache;
+      if (pojoCache == null)
+      {
+         this.config = null;
+         this.plainCacheWrapper = null;
+      }
+      else
+      {
+         this.config = cache.getCache().getConfiguration();
+         this.plainCacheWrapper = buildPlainCacheWrapper(pojoCache);
+      }
+   }
+
+   // ---------------------------------------------------------------  Private methods
+
+   private void constructCache() throws ConfigurationException
+   {
+      pojoCache = (PojoCacheImpl) PojoCacheFactory.createCache(config, false);
+
+      plainCacheWrapper = buildPlainCacheWrapper(pojoCache);
+      if (multiplexerService != null)
+      {
+         injectMuxChannel();
+      }
+   }
+
+   private CacheJmxWrapper buildPlainCacheWrapper(PojoCache pojoCache)
+   {
+      CacheJmxWrapper plainCache = new CacheJmxWrapper();
+      plainCache.setRegisterInterceptors(getRegisterInterceptors());
+      plainCache.setCache(pojoCache.getCache());
+      // It shouldn't send out lifecycle state change notifications for itself; 
+      // we do it
+      plainCache.setDisableStateChangeNotifications(true);
+
+      if (server != null)
+      {
+         plainCache.setNotificationServiceName(cacheObjectName);
+      }
+
+      // Add any NotificationListeners we registered before creating
+      // the CacheJmxWrapper
+      synchronized (pendingListeners)
+      {
+         for (NotificationListenerArgs args : pendingListeners)
+         {
+            plainCache.addNotificationListener(args.listener, args.filter, args.handback);
+         }
+      }
+      return plainCache;
+   }
+
+   private boolean registerPlainCache() throws CacheException
+   {
+      if (registerPlainCache && !plainCacheRegistered && server != null)
+      {
+         try
+         {
+            ObjectName ourName = new ObjectName(cacheObjectName);
+            ObjectName plainName = JmxUtil.getPlainCacheObjectName(ourName);
+            log.debug("Registering plain cache under name " + plainName.getCanonicalName());
+            org.jboss.cache.jmx.JmxUtil.registerCacheMBean(server, plainCacheWrapper, plainName.getCanonicalName());
+            plainCacheRegistered = true;
+            return true;
+         }
+         catch (JMException e)
+         {
+            throw new CacheException("Failed to register plain cache", e);
+         }
+      }
+
+      return false;
+   }
+
+   private void unregisterPlainCache()
+   {
+      if (registerPlainCache && plainCacheRegistered && server != null)
+      {
+         log.debug("Unregistering plain cache");
+         try
+         {
+            org.jboss.cache.jmx.JmxUtil.unregisterCacheMBean(server, plainCacheWrapper.getCacheObjectName());
+         }
+         catch (Exception e)
+         {
+            log.error("Could not unregister plain cache", e);
+         }
+         plainCacheRegistered = false;
+      }
+   }
+
+   private void injectMuxChannel() throws CacheException
+   {
+      Configuration cfg = getConfiguration();
+      RuntimeConfig rtcfg = cfg.getRuntimeConfig();
+
+      // Only inject if there isn't already a channel or factory
+      if (rtcfg.getMuxChannelFactory() != null && rtcfg.getChannel() != null)
+      {
+         Channel ch;
+         try
+         {
+            ch = multiplexerService.createMultiplexerChannel(cfg.getMultiplexerStack(), cfg.getClusterName());
+         }
+         catch (Exception e)
+         {
+            throw new CacheException("Exception creating multiplexed channel", e);
+         }
+         rtcfg.setChannel(ch);
+      }
+
+   }
+
+   /**
+    * Helper for sending out state change notifications
+    */
+   private void sendStateChangeNotification(int oldState, int newState, String msg, Throwable t)
+   {
+      if (plainCacheWrapper != null)
+      {
+         long now = System.currentTimeMillis();
+   
+         AttributeChangeNotification stateChangeNotification = new AttributeChangeNotification(
+                 this,
+                 plainCacheWrapper.getNextNotificationSequenceNumber(), now, msg,
+                 "State", "java.lang.Integer",
+                 new Integer(oldState), new Integer(newState)
+         );
+         stateChangeNotification.setUserData(t);
+   
+         plainCacheWrapper.sendNotification(stateChangeNotification);
+      }
+   }
+
+   /**
+    * Sets the cacheStatus to FAILED and rethrows the problem as one
+    * of the declared types. Converts any non-RuntimeException Exception
+    * to CacheException.
+    *
+    * @param t
+    * @throws PojoCacheException
+    * @throws RuntimeException
+    * @throws Error
+    */
+   private void handleLifecycleTransitionFailure(Throwable t)
+           throws PojoCacheException, RuntimeException, Error
+   {
+      int oldState = getState();
+      cacheStatus = CacheStatus.FAILED;
+      sendStateChangeNotification(oldState, getState(), getClass().getSimpleName() + " failed", t);
+
+      if (t instanceof PojoCacheException)
+         throw (PojoCacheException) t;
+      if (t instanceof CacheException)
+         throw (CacheException) t;
+      else if (t instanceof RuntimeException)
+         throw (RuntimeException) t;
+      else if (t instanceof Error)
+         throw (Error) t;
+      else
+         throw new PojoCacheException(t);
+   }
+
+   private static boolean safeEquals(Object us, Object them)
+   {
+      return (us == null ? them == null : us.equals(them));
+   }
+
+   private static class NotificationListenerArgs
+   {
+      NotificationListener listener;
+      NotificationFilter filter;
+      Object handback;
+
+      NotificationListenerArgs(NotificationListener listener,
+                               NotificationFilter filter,
+                               Object handback)
+      {
+         this.listener = listener;
+         this.filter = filter;
+         this.handback = handback;
+      }
+
+      @Override
+      public boolean equals(Object obj)
+      {
+         if (this == obj) return true;
+
+         if (obj instanceof NotificationListenerArgs)
+         {
+            NotificationListenerArgs other = (NotificationListenerArgs) obj;
+            if (safeEquals(listener, other.listener)
+                    && safeEquals(filter, other.filter)
+                    && safeEquals(handback, other.handback))
+            {
+               return true;
+            }
+         }
+         return false;
+      }
+
+      @Override
+      public int hashCode()
+      {
+         int result = 17;
+         result = 29 * result + (listener != null ? listener.hashCode() : 0);
+         result = 29 * result + (filter != null ? filter.hashCode() : 0);
+         result = 29 * result + (handback != null ? handback.hashCode() : 0);
+         return result;
+      }
+   }
+
+}

Copied: pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/FindReferencesTest.java (from rev 6374, pojo/trunk/src/test/java/org/jboss/cache/pojo/FindReferencesTest.java)
===================================================================
--- pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/FindReferencesTest.java	                        (rev 0)
+++ pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/FindReferencesTest.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -0,0 +1,155 @@
+package org.jboss.cache.pojo;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertTrue;
+
+import java.util.*;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.pojo.impl.ReferenceImpl;
+import org.jboss.cache.pojo.test.*;
+import org.testng.annotations.*;
+
+/**
+ * Test case for finding back-references.
+ *
+ * @author Dan Berindei <dan.berindei at gmail.com>
+ */
+
+ at Test(groups = { "functional" })
+public class FindReferencesTest
+{
+   Log log = LogFactory.getLog(FindReferencesTest.class);
+   PojoCache cache_;
+
+   @BeforeMethod(alwaysRun = true)
+   protected void setUp() throws Exception
+   {
+      log.info("setUp() ....");
+      String configFile = "META-INF/local-service.xml";
+      boolean toStart = false;
+      cache_ = PojoCacheFactory.createCache(configFile, toStart);
+      cache_.start();
+   }
+
+   @AfterMethod(alwaysRun = true)
+   protected void tearDown() throws Exception
+   {
+      cache_.stop();
+   }
+
+   private Person createPerson(String id, String name, int age, Address address)
+   {
+      Person p = new Person(null);
+      p.setName(name);
+      p.setAge(age);
+      p.setAddress(address);
+      cache_.attach(id, p);
+      return p;
+   }
+
+   private Address createAddress()
+   {
+      Address add = new Address();
+      add.setZip(95123);
+      add.setCity("San Jose");
+      return add;
+   }
+
+   public void testImmediateType() throws Exception
+   {
+      log.info("testImmediateType() ....");
+      String test = "This is a test";
+      cache_.attach("/test", test);
+
+      assertEquals("Fqn", null, cache_.getInternalFqn(test));
+      assertEquals("List", Collections.EMPTY_LIST, cache_.getReferences(test));
+   }
+
+   public void testNotAttached() throws Exception
+   {
+      log.info("testImmediateType() ....");
+      Address address = createAddress();
+
+      assertEquals("Fqn", null, cache_.getInternalFqn(address));
+      assertEquals("List", Collections.EMPTY_LIST, cache_.getReferences(address));
+   }
+
+   public void testSingleExternalReference() throws Exception
+   {
+      log.info("testNoReferences() ....");
+      Person joe = createPerson("/person/joe", "Joe Black", 32, null);
+
+      Fqn<?> joesInternalFqn = cache_.getInternalFqn(joe);
+      assertTrue("Internal Fqn not null", joesInternalFqn != null);
+
+      Collection<Reference> addressReferences = cache_.getReferences(joe);
+      assertEquals("Size", 1, addressReferences.size());
+      assertEquals("Reference", new ReferenceImpl(Fqn.fromString("/person/joe"), null),
+            addressReferences.iterator().next());
+   }
+
+   public void testSingleInternalReference() throws Exception
+   {
+      log.info("testSingleReference() ....");
+      Address address = createAddress();
+      Person joe = createPerson("/person/joe", "Joe Black", 32, address);
+
+      Fqn<?> joesInternalFqn = cache_.getInternalFqn(joe);
+      Collection<Reference> addressReferences = cache_.getReferences(address);
+
+      assertEquals("Size", 1, addressReferences.size());
+      assertEquals("Reference", new ReferenceImpl(joesInternalFqn, "address"),
+            addressReferences.iterator().next());
+   }
+
+   public void testMultipleInternalReferences() throws Exception
+   {
+      log.info("testMultipleReferences() ....");
+      Address address = createAddress();
+      Person joe = createPerson("/person/joe", "Joe Black", 32, address);
+      Person jane = createPerson("/person/jane", "Jane Black", 32, address);
+
+      Fqn<?> joesInternalFqn = cache_.getInternalFqn(joe);
+      Fqn<?> janesInternalFqn = cache_.getInternalFqn(jane);
+      HashSet<Reference> expectedReferences = new HashSet<Reference>(Arrays.<Reference> asList(
+            new ReferenceImpl(joesInternalFqn, "address"), new ReferenceImpl(janesInternalFqn, "address")));
+
+      Set<Reference> addressReferences = new HashSet<Reference>(cache_.getReferences(address));
+
+      assertEquals("Reference Fqns", expectedReferences, addressReferences);
+   }
+
+   public void testDoubleReferenceFromSameObject()
+   {
+      log.info("testDoubleReferenceFromSameObject() ...");
+
+      DoubleRef doubleRef = new DoubleRef();
+      cache_.attach("/doubleref", doubleRef);
+
+      Fqn<?> sourceFqn = cache_.getInternalFqn(doubleRef);
+      HashSet<Reference> expectedReferences = new HashSet<Reference>(Arrays.<Reference> asList(
+            new ReferenceImpl(sourceFqn, "one"), new ReferenceImpl(sourceFqn, "two")));
+
+      Student student = doubleRef.getOne();
+      Set<Reference> references = new HashSet<Reference>(cache_.getReferences(student));
+
+      assertEquals("Reference Fqns", expectedReferences, references);
+
+      // removing one of the references
+      doubleRef.setOne(null);
+      Collection<Reference> references2 = cache_.getReferences(student);
+
+      assertEquals("Size", 1, references2.size());
+      assertEquals("Reference Fqn", new ReferenceImpl(sourceFqn, "two"), references2.iterator().next());
+
+      // removing the last reference
+      doubleRef.setTwo(null);
+      Collection<Reference> references3 = cache_.getReferences(student);
+
+      assertEquals("Size", 0, references3.size());
+   }
+
+}
\ No newline at end of file

Deleted: pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ListTest.java
===================================================================
--- pojo/trunk/src/test/java/org/jboss/cache/pojo/notification/ListTest.java	2008-07-16 17:30:08 UTC (rev 6310)
+++ pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ListTest.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -1,260 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.cache.pojo.notification;
-
-import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertSame;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.jboss.cache.pojo.PojoCache;
-import org.jboss.cache.pojo.PojoCacheFactory;
-import org.jboss.cache.pojo.notification.event.AttachedEvent;
-import org.jboss.cache.pojo.notification.event.DetachedEvent;
-import org.jboss.cache.pojo.notification.event.Event;
-import org.jboss.cache.pojo.notification.event.ListModifiedEvent;
-import org.jboss.cache.pojo.test.Person;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-//$Id$
-
-/**
- * Tests list notifications
- *
- * @author Jason T. Greene
- */
- at Test(groups = {"functional"})
-public class ListTest
-{
-   protected PojoCache cache;
-   protected Listener listener = new Listener();
-
-
-   @BeforeMethod(alwaysRun = true)
-   protected void setUp() throws Exception
-   {
-      String configFile = "META-INF/local-service.xml";
-      boolean toStart = false;
-      cache = PojoCacheFactory.createCache(configFile, toStart);
-      cache.start();
-      cache.addListener(listener);
-   }
-
-   @AfterMethod(alwaysRun = true)
-   protected void tearDown() throws Exception
-   {
-      cache.stop();
-      listener.clear();
-   }
-
-   private <T extends Event> T takeNotification(Class<T> clazz)
-   {
-      T notification = listener.take(clazz);
-      verifyNotification(notification);
-
-      return notification;
-   }
-
-   protected void verifyNotification(Event notification)
-   {
-      assertSame(cache, notification.getContext().getPojoCache());
-      assertEquals(true, notification.isLocal());
-   }
-
-   @SuppressWarnings("unchecked")
-   public void testListAddNotification() throws Exception
-   {
-      final String test1 = "test1";
-      final String test2 = "test2";
-
-      List<String> list = new ArrayList<String>();
-      list.add(test1);
-      list.add(test2);
-      cache.attach("a", list);
-      list = (List<String>) cache.find("a");
-
-      // String attach
-      AttachedEvent attach = (AttachedEvent) takeNotification(AttachedEvent.class);
-      assertEquals(test1, attach.getSource());
-
-      // List add
-      ListModifiedEvent modify = takeNotification(ListModifiedEvent.class);
-      assertEquals(ListModifiedEvent.Operation.ADD, modify.getOperation());
-      assertEquals(test1, modify.getValue());
-      assertEquals(0, modify.getIndex());
-
-      // String attach
-      attach = takeNotification(AttachedEvent.class);
-      assertEquals(test2, attach.getSource());
-
-      // List add
-      modify = takeNotification(ListModifiedEvent.class);
-      assertEquals(ListModifiedEvent.Operation.ADD, modify.getOperation());
-      assertEquals(test2, modify.getValue());
-      assertEquals(1, modify.getIndex());
-
-      // List Attach
-      attach = takeNotification(AttachedEvent.class);
-      assertEquals(list, attach.getSource());
-
-   }
-
-   @SuppressWarnings("unchecked")
-   public void testListSetNotification() throws Exception
-   {
-      final String test1 = "test1";
-      final String test2 = "test2";
-
-      List<String> list = new ArrayList<String>();
-      list.add(test1);
-      cache.attach("a", list);
-      list = (List<String>) cache.find("a");
-      list.set(0, test2);
-
-      // String attach
-      AttachedEvent attach = takeNotification(AttachedEvent.class);
-      assertEquals(test1, attach.getSource());
-
-      // List add
-      ListModifiedEvent modify = takeNotification(ListModifiedEvent.class);
-      assertEquals(ListModifiedEvent.Operation.ADD, modify.getOperation());
-      assertEquals(test1, modify.getValue());
-      assertEquals(0, modify.getIndex());
-
-      // List Attach
-      attach = takeNotification(AttachedEvent.class);
-      assertEquals(list, attach.getSource());
-
-      // String detach
-      DetachedEvent detach = takeNotification(DetachedEvent.class);
-      assertEquals(test1, detach.getSource());
-
-      // String attach
-      attach = takeNotification(AttachedEvent.class);
-      assertEquals(test2, attach.getSource());
-
-      // List set
-      modify = takeNotification(ListModifiedEvent.class);
-      assertEquals(ListModifiedEvent.Operation.SET, modify.getOperation());
-      assertEquals(test2, modify.getValue());
-      assertEquals(0, modify.getIndex());
-   }
-
-   @SuppressWarnings("unchecked")
-   public void testListRemoveNotification() throws Exception
-   {
-      final String test1 = "test1";
-      final String test2 = "test2";
-
-      List<String> list = new ArrayList<String>();
-      list.add(test1);
-      list.add(test2);
-      cache.attach("a", list);
-      list = (List<String>) cache.find("a");
-      list.remove(1);
-
-      // String attach
-      AttachedEvent attach = takeNotification(AttachedEvent.class);
-      assertEquals(test1, attach.getSource());
-
-      // List add
-      ListModifiedEvent modify = takeNotification(ListModifiedEvent.class);
-      assertEquals(ListModifiedEvent.Operation.ADD, modify.getOperation());
-      assertEquals(test1, modify.getValue());
-      assertEquals(0, modify.getIndex());
-
-      // String attach
-      attach = takeNotification(AttachedEvent.class);
-      assertEquals(test2, attach.getSource());
-
-      // List add
-      modify = takeNotification(ListModifiedEvent.class);
-      assertEquals(ListModifiedEvent.Operation.ADD, modify.getOperation());
-      assertEquals(test2, modify.getValue());
-      assertEquals(1, modify.getIndex());
-
-      // List Attach
-      attach = takeNotification(AttachedEvent.class);
-      assertEquals(list, attach.getSource());
-
-      // List remove
-      modify = takeNotification(ListModifiedEvent.class);
-      assertEquals(ListModifiedEvent.Operation.REMOVE, modify.getOperation());
-      assertEquals(test2, modify.getValue());
-      assertEquals(1, modify.getIndex());
-
-      // String detach
-      DetachedEvent detach = takeNotification(DetachedEvent.class);
-      assertEquals(test2, detach.getSource());
-   }
-
-   public void testObjectListAdd() throws Exception
-   {
-      final String english = "English";
-      final String taiwanese = "Taiwanese";
-
-      Person test = new Person();
-      test.setName("Ben");
-      test.setAge(10);
-
-      ArrayList<String> list = new ArrayList<String>();
-
-      list.add(english);
-      list.add(taiwanese);
-      test.setLanguages(list);
-
-      cache.attach("a", test);
-
-      // String attach
-      AttachedEvent attach = takeNotification(AttachedEvent.class);
-      assertEquals(english, attach.getSource());
-
-      // List add
-      ListModifiedEvent modify = takeNotification(ListModifiedEvent.class);
-      assertEquals(ListModifiedEvent.Operation.ADD, modify.getOperation());
-      assertEquals(english, modify.getValue());
-      assertEquals(0, modify.getIndex());
-
-      // String attach
-      attach = takeNotification(AttachedEvent.class);
-      assertEquals(taiwanese, attach.getSource());
-
-      // List add
-      modify = takeNotification(ListModifiedEvent.class);
-      assertEquals(ListModifiedEvent.Operation.ADD, modify.getOperation());
-      assertEquals(taiwanese, modify.getValue());
-      assertEquals(1, modify.getIndex());
-
-      // List Attach
-      attach = takeNotification(AttachedEvent.class);
-      assertEquals(test.getLanguages(), attach.getSource());
-
-      // Person Attach
-      attach = takeNotification(AttachedEvent.class);
-      assertEquals(test, attach.getSource());
-   }
-
-
-}

Copied: pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ListTest.java (from rev 6323, pojo/trunk/src/test/java/org/jboss/cache/pojo/notification/ListTest.java)
===================================================================
--- pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ListTest.java	                        (rev 0)
+++ pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ListTest.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -0,0 +1,264 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.cache.pojo.notification;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertSame;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.cache.pojo.PojoCache;
+import org.jboss.cache.pojo.PojoCacheFactory;
+import org.jboss.cache.pojo.notification.event.AttachedEvent;
+import org.jboss.cache.pojo.notification.event.DetachedEvent;
+import org.jboss.cache.pojo.notification.event.Event;
+import org.jboss.cache.pojo.notification.event.ListModifiedEvent;
+import org.jboss.cache.pojo.test.Person;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+//$Id$
+
+/**
+ * Tests list notifications
+ *
+ * @author Jason T. Greene
+ */
+ at Test(groups = {"functional"})
+public class ListTest
+{
+   protected PojoCache cache;
+   protected Listener listener = new Listener();
+
+
+   @BeforeMethod(alwaysRun = true)
+   protected void setUp() throws Exception
+   {
+      String configFile = "META-INF/local-service.xml";
+      boolean toStart = false;
+      cache = PojoCacheFactory.createCache(configFile, toStart);
+      cache.start();
+      cache.addListener(listener);
+   }
+
+   @AfterMethod(alwaysRun = true)
+   protected void tearDown() throws Exception
+   {
+      cache.stop();
+      listener.clear();
+   }
+
+   private <T extends Event> T takeNotification(Class<T> clazz)
+   {
+      T notification = listener.take(clazz);
+      verifyNotification(notification);
+
+      return notification;
+   }
+
+   protected void verifyNotification(Event notification)
+   {
+      assertSame(cache, notification.getContext().getPojoCache());
+      assertEquals(true, notification.isLocal());
+   }
+
+   @SuppressWarnings("unchecked")
+   public void testListAddNotification() throws Exception
+   {
+      final String test1 = "test1";
+      final String test2 = "test2";
+
+      List<String> list = new ArrayList<String>();
+      list.add(test1);
+      list.add(test2);
+      cache.attach("a", list);
+      list = (List<String>) cache.find("a");
+
+      // String attach
+      AttachedEvent attach = (AttachedEvent) takeNotification(AttachedEvent.class);
+      assertEquals(test1, attach.getSource());
+
+      // List add
+      ListModifiedEvent modify = takeNotification(ListModifiedEvent.class);
+      assertEquals(ListModifiedEvent.Operation.ADD, modify.getOperation());
+      assertEquals(test1, modify.getValue());
+      assertEquals(0, modify.getIndex());
+
+      // String attach
+      attach = takeNotification(AttachedEvent.class);
+      assertEquals(test2, attach.getSource());
+
+      // List add
+      modify = takeNotification(ListModifiedEvent.class);
+      assertEquals(ListModifiedEvent.Operation.ADD, modify.getOperation());
+      assertEquals(test2, modify.getValue());
+      assertEquals(1, modify.getIndex());
+
+      // List Attach
+      attach = takeNotification(AttachedEvent.class);
+      assertEquals(list, attach.getSource());
+      //cache.detach("a");
+   }
+
+   @SuppressWarnings("unchecked")
+   public void testListSetNotification() throws Exception
+   {
+      final String test1 = "test1";
+      final String test2 = "test2";
+
+      List<String> list = new ArrayList<String>();
+      list.add(test1);
+      cache.attach("b", list);
+      list = (List<String>) cache.find("b");
+      list.set(0, test2);
+
+      // String attach
+      AttachedEvent attach = takeNotification(AttachedEvent.class);
+      assertEquals(test1, attach.getSource());
+
+      // List add
+      ListModifiedEvent modify = takeNotification(ListModifiedEvent.class);
+      assertEquals(ListModifiedEvent.Operation.ADD, modify.getOperation());
+      assertEquals(test1, modify.getValue());
+      assertEquals(0, modify.getIndex());
+
+      // List Attach
+      attach = takeNotification(AttachedEvent.class);
+      assertEquals(list, attach.getSource());
+
+      // String detach
+      DetachedEvent detach = takeNotification(DetachedEvent.class);
+      assertEquals(test1, detach.getSource());
+
+      // String attach
+      attach = takeNotification(AttachedEvent.class);
+      assertEquals(test2, attach.getSource());
+
+      // List set
+      modify = takeNotification(ListModifiedEvent.class);
+      assertEquals(ListModifiedEvent.Operation.SET, modify.getOperation());
+      assertEquals(test2, modify.getValue());
+      assertEquals(0, modify.getIndex());
+      //cache.detach("b");
+   }
+
+   @SuppressWarnings("unchecked")
+   public void testListRemoveNotification() throws Exception
+   {
+      final String test1 = "test1";
+      final String test2 = "test2";
+
+      List<String> list = new ArrayList<String>();
+      list.add(test1);
+      list.add(test2);
+      cache.attach("c", list);
+      list = (List<String>) cache.find("c");
+      list.remove(1);
+
+      // String attach
+      AttachedEvent attach = takeNotification(AttachedEvent.class);
+      assertEquals(test1, attach.getSource());
+
+      // List add
+      ListModifiedEvent modify = takeNotification(ListModifiedEvent.class);
+      assertEquals(ListModifiedEvent.Operation.ADD, modify.getOperation());
+      assertEquals(test1, modify.getValue());
+      assertEquals(0, modify.getIndex());
+
+      // String attach
+      attach = takeNotification(AttachedEvent.class);
+      assertEquals(test2, attach.getSource());
+
+      // List add
+      modify = takeNotification(ListModifiedEvent.class);
+      assertEquals(ListModifiedEvent.Operation.ADD, modify.getOperation());
+      assertEquals(test2, modify.getValue());
+      assertEquals(1, modify.getIndex());
+
+      // List Attach
+      attach = takeNotification(AttachedEvent.class);
+      assertEquals(list, attach.getSource());
+
+      // List remove
+      modify = takeNotification(ListModifiedEvent.class);
+      assertEquals(ListModifiedEvent.Operation.REMOVE, modify.getOperation());
+      assertEquals(test2, modify.getValue());
+      assertEquals(1, modify.getIndex());
+
+      // String detach
+      DetachedEvent detach = takeNotification(DetachedEvent.class);
+      assertEquals(test2, detach.getSource());
+      //cache.detach("c");
+   }
+
+   public void testObjectListAdd() throws Exception
+   {
+      final String english = "English";
+      final String taiwanese = "Taiwanese";
+
+      Person test = new Person();
+      test.setName("Ben");
+      test.setAge(10);
+
+      ArrayList<String> list = new ArrayList<String>();
+
+      list.add(english);
+      list.add(taiwanese);
+      test.setLanguages(list);
+
+      cache.attach("d", test);
+
+      // String attach
+      AttachedEvent attach = takeNotification(AttachedEvent.class);
+      assertEquals(english, attach.getSource());
+
+      // List add
+      ListModifiedEvent modify = takeNotification(ListModifiedEvent.class);
+      assertEquals(ListModifiedEvent.Operation.ADD, modify.getOperation());
+      assertEquals(english, modify.getValue());
+      assertEquals(0, modify.getIndex());
+
+      // String attach
+      attach = takeNotification(AttachedEvent.class);
+      assertEquals(taiwanese, attach.getSource());
+
+      // List add
+      modify = takeNotification(ListModifiedEvent.class);
+      assertEquals(ListModifiedEvent.Operation.ADD, modify.getOperation());
+      assertEquals(taiwanese, modify.getValue());
+      assertEquals(1, modify.getIndex());
+
+      // List Attach
+      attach = takeNotification(AttachedEvent.class);
+      assertEquals(test.getLanguages(), attach.getSource());
+
+      // Person Attach
+      attach = takeNotification(AttachedEvent.class);
+      assertEquals(test, attach.getSource());
+
+      //cache.detach("d");
+   }
+
+
+}

Deleted: pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/Listener.java
===================================================================
--- pojo/trunk/src/test/java/org/jboss/cache/pojo/notification/Listener.java	2008-07-16 17:30:08 UTC (rev 6310)
+++ pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/Listener.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -1,77 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-
-package org.jboss.cache.pojo.notification;
-
-import java.util.LinkedList;
-import java.util.Queue;
-
-import net.jcip.annotations.NotThreadSafe;
-
-import org.jboss.cache.pojo.notification.annotation.Attached;
-import org.jboss.cache.pojo.notification.annotation.Detached;
-import org.jboss.cache.pojo.notification.annotation.FieldModified;
-import org.jboss.cache.pojo.notification.annotation.ListModified;
-import org.jboss.cache.pojo.notification.annotation.MapModified;
-import org.jboss.cache.pojo.notification.annotation.PojoCacheListener;
-import org.jboss.cache.pojo.notification.annotation.SetModified;
-import org.jboss.cache.pojo.notification.event.Event;
-
-// $Id$
-
-/**
- * A recoding Listener for notification test package. This is not thread safe, just for testing.
- *
- * @author Jason T. Greene
- */
- at PojoCacheListener
- at NotThreadSafe
-public class Listener
-{
-   private Queue<Event> events = new LinkedList<Event>();
-
-   @SuppressWarnings("unchecked")
-   public <T extends Event> T take(Class<T> t)
-   {
-      Event notification = events.remove();
-      if (!t.isInstance(notification))
-         throw new IllegalStateException("Expected notification type: " + t.getSimpleName() + " but was: " + notification.getClass().getSimpleName());
-
-      return (T) notification;
-   }
-
-   public void clear()
-   {
-      events.clear();
-   }
-
-   @Attached
-   @Detached
-   @FieldModified
-   @ListModified
-   @SetModified
-   @MapModified
-   public void handle(Event event)
-   {
-      events.offer(event);
-   }
-}
\ No newline at end of file

Copied: pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/Listener.java (from rev 6323, pojo/trunk/src/test/java/org/jboss/cache/pojo/notification/Listener.java)
===================================================================
--- pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/Listener.java	                        (rev 0)
+++ pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/Listener.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -0,0 +1,82 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+
+package org.jboss.cache.pojo.notification;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import org.jboss.cache.pojo.notification.annotation.Attached;
+import org.jboss.cache.pojo.notification.annotation.Detached;
+import org.jboss.cache.pojo.notification.annotation.FieldModified;
+import org.jboss.cache.pojo.notification.annotation.ListModified;
+import org.jboss.cache.pojo.notification.annotation.MapModified;
+import org.jboss.cache.pojo.notification.annotation.PojoCacheListener;
+import org.jboss.cache.pojo.notification.annotation.SetModified;
+import org.jboss.cache.pojo.notification.event.Event;
+
+// $Id$
+
+/**
+ * A recoding Listener for notification test package.
+ *
+ * @author Jason T. Greene
+ */
+ at PojoCacheListener
+public class Listener
+{
+   private BlockingQueue<Event> events = new LinkedBlockingQueue<Event>();
+
+   @SuppressWarnings("unchecked")
+   public <T extends Event> T take(Class<T> t)
+   {
+      Event notification;
+      try
+      {
+         notification = events.take();
+      }
+      catch (InterruptedException e)
+      {
+         throw new RuntimeException(e);
+      }
+      if (!t.isInstance(notification))
+         throw new IllegalStateException("Expected notification type: " + t.getSimpleName() + " but was: " + notification.getClass().getSimpleName());
+
+      return (T) notification;
+   }
+
+   public void clear()
+   {
+      events.clear();
+   }
+
+   @Attached
+   @Detached
+   @FieldModified
+   @ListModified
+   @SetModified
+   @MapModified
+   public void handle(Event event)
+   {
+      events.offer(event);
+   }
+}
\ No newline at end of file

Deleted: pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/MapTest.java
===================================================================
--- pojo/trunk/src/test/java/org/jboss/cache/pojo/notification/MapTest.java	2008-07-16 17:30:08 UTC (rev 6310)
+++ pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/MapTest.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -1,224 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.cache.pojo.notification;
-
-import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertSame;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-import org.jboss.cache.pojo.PojoCache;
-import org.jboss.cache.pojo.PojoCacheFactory;
-import org.jboss.cache.pojo.notification.event.AttachedEvent;
-import org.jboss.cache.pojo.notification.event.DetachedEvent;
-import org.jboss.cache.pojo.notification.event.Event;
-import org.jboss.cache.pojo.notification.event.MapModifiedEvent;
-import org.jboss.cache.pojo.test.Person;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-//$Id$
-
-/**
- * Tests map notifications
- *
- * @author Jason T. Greene
- */
- at Test(groups = {"functional"})
-public class MapTest
-{
-   protected PojoCache cache;
-   protected Listener listener = new Listener();
-
-
-   @BeforeMethod(alwaysRun = true)
-   protected void setUp() throws Exception
-   {
-      String configFile = "META-INF/local-service.xml";
-      boolean toStart = false;
-      cache = PojoCacheFactory.createCache(configFile, toStart);
-      cache.start();
-      cache.addListener(listener);
-   }
-
-
-   @AfterMethod(alwaysRun = true)
-   protected void tearDown() throws Exception
-   {
-      cache.stop();
-      listener.clear();
-   }
-
-   private <T extends Event> T takeNotification(Class<T> clazz)
-   {
-      T notification = listener.take(clazz);
-      verifyNotification(notification);
-
-      return notification;
-   }
-
-   protected void verifyNotification(Event notification)
-   {
-      assertSame(cache, notification.getContext().getPojoCache());
-      assertEquals(true, notification.isLocal());
-   }
-
-   @SuppressWarnings("unchecked")
-   public void testMapAddNotification() throws Exception
-   {
-      final String key1 = "key1";
-      final String key2 = "key2";
-      final String test1 = "test1";
-      final String test2 = "test2";
-
-      Map<String, String> map = new LinkedHashMap<String, String>();
-      map.put(key1, test1);
-      map.put(key2, test2);
-      cache.attach("a", map);
-      map = (Map<String, String>) cache.find("a");
-
-      // String attach
-      AttachedEvent attach = takeNotification(AttachedEvent.class);
-      assertEquals(test1, attach.getSource());
-
-      // Map put
-      MapModifiedEvent modify = takeNotification(MapModifiedEvent.class);
-      assertEquals(MapModifiedEvent.Operation.PUT, modify.getOperation());
-      assertEquals(key1, modify.getKey());
-      assertEquals(test1, modify.getValue());
-
-      // String attach
-      attach = takeNotification(AttachedEvent.class);
-      assertEquals(test2, attach.getSource());
-
-      // Map put
-      modify = takeNotification(MapModifiedEvent.class);
-      assertEquals(MapModifiedEvent.Operation.PUT, modify.getOperation());
-      assertEquals(key2, modify.getKey());
-      assertEquals(test2, modify.getValue());
-
-      // Map Attach
-      attach = takeNotification(AttachedEvent.class);
-      assertEquals(map, attach.getSource());
-
-   }
-
-   @SuppressWarnings("unchecked")
-   public void testMapRemoveNotification() throws Exception
-   {
-      final String key1 = "key1";
-      final String key2 = "key2";
-      final String test1 = "test1";
-      final String test2 = "test2";
-
-      Map<String, String> map = new LinkedHashMap<String, String>();
-      map.put(key1, test1);
-      map.put(key2, test2);
-      cache.attach("a", map);
-      map = (Map<String, String>) cache.find("a");
-      map.remove(key2);
-
-      // String attach
-      AttachedEvent attach = takeNotification(AttachedEvent.class);
-      assertEquals(test1, attach.getSource());
-
-      // Map put
-      MapModifiedEvent modify = takeNotification(MapModifiedEvent.class);
-      assertEquals(MapModifiedEvent.Operation.PUT, modify.getOperation());
-      assertEquals(key1, modify.getKey());
-      assertEquals(test1, modify.getValue());
-
-      // String attach
-      attach = takeNotification(AttachedEvent.class);
-      assertEquals(test2, attach.getSource());
-
-      // Map put
-      modify = takeNotification(MapModifiedEvent.class);
-      assertEquals(MapModifiedEvent.Operation.PUT, modify.getOperation());
-      assertEquals(key2, modify.getKey());
-      assertEquals(test2, modify.getValue());
-
-      // Map Attach
-      attach = takeNotification(AttachedEvent.class);
-      assertEquals(map, attach.getSource());
-
-      // Map remove
-      modify = takeNotification(MapModifiedEvent.class);
-      assertEquals(MapModifiedEvent.Operation.REMOVE, modify.getOperation());
-      assertEquals(key2, modify.getKey());
-      assertEquals(test2, modify.getValue());
-
-      // String detach
-      DetachedEvent detach = takeNotification(DetachedEvent.class);
-      assertEquals(test2, detach.getSource());
-   }
-
-   public void testObjectMapAdd() throws Exception
-   {
-      final String key1 = "key1";
-      final String key2 = "key2";
-      final String drumming = "druming";
-      final String engineering = "engineering";
-
-      Person test = new Person();
-      test.setName("Joe");
-      test.setAge(30);
-
-      Map<String, String> map = new LinkedHashMap<String, String>();
-      map.put(key1, drumming);
-      map.put(key2, engineering);
-      test.setHobbies(map);
-      cache.attach("a", test);
-
-      // String attach
-      AttachedEvent attach = takeNotification(AttachedEvent.class);
-      assertEquals(drumming, attach.getSource());
-
-      // Map put
-      MapModifiedEvent modify = takeNotification(MapModifiedEvent.class);
-      assertEquals(MapModifiedEvent.Operation.PUT, modify.getOperation());
-      assertEquals(key1, modify.getKey());
-      assertEquals(drumming, modify.getValue());
-
-      // String attach
-      attach = takeNotification(AttachedEvent.class);
-      assertEquals(engineering, attach.getSource());
-
-      // Map put
-      modify = takeNotification(MapModifiedEvent.class);
-      assertEquals(key2, modify.getKey());
-      assertEquals(MapModifiedEvent.Operation.PUT, modify.getOperation());
-      assertEquals(engineering, modify.getValue());
-
-      // Map Attach
-      attach = takeNotification(AttachedEvent.class);
-      assertEquals(test.getHobbies(), attach.getSource());
-
-      // Person Attach
-      attach = takeNotification(AttachedEvent.class);
-      assertEquals(test, attach.getSource());
-   }
-
-
-}

Copied: pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/MapTest.java (from rev 6323, pojo/trunk/src/test/java/org/jboss/cache/pojo/notification/MapTest.java)
===================================================================
--- pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/MapTest.java	                        (rev 0)
+++ pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/MapTest.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -0,0 +1,229 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.cache.pojo.notification;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertSame;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.jboss.cache.pojo.PojoCache;
+import org.jboss.cache.pojo.PojoCacheFactory;
+import org.jboss.cache.pojo.notification.event.AttachedEvent;
+import org.jboss.cache.pojo.notification.event.DetachedEvent;
+import org.jboss.cache.pojo.notification.event.Event;
+import org.jboss.cache.pojo.notification.event.MapModifiedEvent;
+import org.jboss.cache.pojo.test.Person;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+//$Id$
+
+/**
+ * Tests map notifications
+ *
+ * @author Jason T. Greene
+ */
+ at Test(groups = {"functional"})
+public class MapTest
+{
+   protected PojoCache cache;
+   protected Listener listener = new Listener();
+
+   @BeforeMethod(alwaysRun = true)
+   protected void setUp() throws Exception
+   {
+      String configFile = "META-INF/local-service.xml";
+      boolean toStart = false;
+      cache = PojoCacheFactory.createCache(configFile, toStart);
+      cache.start();
+      cache.addListener(listener);
+   }
+
+
+   @AfterMethod(alwaysRun = true)
+   protected void tearDown() throws Exception
+   {
+      cache.stop();
+      listener.clear();
+   }
+
+   private <T extends Event> T takeNotification(Class<T> clazz)
+   {
+      T notification = listener.take(clazz);
+      verifyNotification(notification);
+
+      return notification;
+   }
+
+   protected void verifyNotification(Event notification)
+   {
+      assertSame(cache, notification.getContext().getPojoCache());
+      assertEquals(true, notification.isLocal());
+   }
+
+   @SuppressWarnings("unchecked")
+   public void testMapAddNotification() throws Exception
+   {
+      final String key1 = "key1";
+      final String key2 = "key2";
+      final String test1 = "test1";
+      final String test2 = "test2";
+
+      Map<String, String> map = new LinkedHashMap<String, String>();
+      map.put(key1, test1);
+      map.put(key2, test2);
+      cache.attach("a", map);
+      map = (Map<String, String>) cache.find("a");
+
+      // String attach
+      AttachedEvent attach = takeNotification(AttachedEvent.class);
+      assertEquals(test1, attach.getSource());
+
+      // Map put
+      MapModifiedEvent modify = takeNotification(MapModifiedEvent.class);
+      assertEquals(MapModifiedEvent.Operation.PUT, modify.getOperation());
+      assertEquals(key1, modify.getKey());
+      assertEquals(test1, modify.getValue());
+
+      // String attach
+      attach = takeNotification(AttachedEvent.class);
+      assertEquals(test2, attach.getSource());
+
+      // Map put
+      modify = takeNotification(MapModifiedEvent.class);
+      assertEquals(MapModifiedEvent.Operation.PUT, modify.getOperation());
+      assertEquals(key2, modify.getKey());
+      assertEquals(test2, modify.getValue());
+
+      // Map Attach
+      attach = takeNotification(AttachedEvent.class);
+      assertEquals(map, attach.getSource());
+
+      //cache.detach("a");
+
+   }
+
+   @SuppressWarnings("unchecked")
+   public void testMapRemoveNotification() throws Exception
+   {
+      final String key1 = "key1";
+      final String key2 = "key2";
+      final String test1 = "test1";
+      final String test2 = "test2";
+
+      Map<String, String> map = new LinkedHashMap<String, String>();
+      map.put(key1, test1);
+      map.put(key2, test2);
+      cache.attach("b", map);
+      map = (Map<String, String>) cache.find("b");
+      map.remove(key2);
+
+      // String attach
+      AttachedEvent attach = takeNotification(AttachedEvent.class);
+      assertEquals(test1, attach.getSource());
+
+      // Map put
+      MapModifiedEvent modify = takeNotification(MapModifiedEvent.class);
+      assertEquals(MapModifiedEvent.Operation.PUT, modify.getOperation());
+      assertEquals(key1, modify.getKey());
+      assertEquals(test1, modify.getValue());
+
+      // String attach
+      attach = takeNotification(AttachedEvent.class);
+      assertEquals(test2, attach.getSource());
+
+      // Map put
+      modify = takeNotification(MapModifiedEvent.class);
+      assertEquals(MapModifiedEvent.Operation.PUT, modify.getOperation());
+      assertEquals(key2, modify.getKey());
+      assertEquals(test2, modify.getValue());
+
+      // Map Attach
+      attach = takeNotification(AttachedEvent.class);
+      assertEquals(map, attach.getSource());
+
+      // Map remove
+      modify = takeNotification(MapModifiedEvent.class);
+      assertEquals(MapModifiedEvent.Operation.REMOVE, modify.getOperation());
+      assertEquals(key2, modify.getKey());
+      assertEquals(test2, modify.getValue());
+
+      // String detach
+      DetachedEvent detach = takeNotification(DetachedEvent.class);
+      assertEquals(test2, detach.getSource());
+
+      //cache.detach("b");
+   }
+
+   public void testObjectMapAdd() throws Exception
+   {
+      final String key1 = "key1";
+      final String key2 = "key2";
+      final String drumming = "druming";
+      final String engineering = "engineering";
+
+      Person test = new Person();
+      test.setName("Joe");
+      test.setAge(30);
+
+      Map<String, String> map = new LinkedHashMap<String, String>();
+      map.put(key1, drumming);
+      map.put(key2, engineering);
+      test.setHobbies(map);
+      cache.attach("c", test);
+
+      // String attach
+      AttachedEvent attach = takeNotification(AttachedEvent.class);
+      assertEquals(drumming, attach.getSource());
+
+      // Map put
+      MapModifiedEvent modify = takeNotification(MapModifiedEvent.class);
+      assertEquals(MapModifiedEvent.Operation.PUT, modify.getOperation());
+      assertEquals(key1, modify.getKey());
+      assertEquals(drumming, modify.getValue());
+
+      // String attach
+      attach = takeNotification(AttachedEvent.class);
+      assertEquals(engineering, attach.getSource());
+
+      // Map put
+      modify = takeNotification(MapModifiedEvent.class);
+      assertEquals(key2, modify.getKey());
+      assertEquals(MapModifiedEvent.Operation.PUT, modify.getOperation());
+      assertEquals(engineering, modify.getValue());
+
+      // Map Attach
+      attach = takeNotification(AttachedEvent.class);
+      assertEquals(test.getHobbies(), attach.getSource());
+
+      // Person Attach
+      attach = takeNotification(AttachedEvent.class);
+      assertEquals(test, attach.getSource());
+
+      //cache.detach("c");
+   }
+
+
+}

Deleted: pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ObjectTest.java
===================================================================
--- pojo/trunk/src/test/java/org/jboss/cache/pojo/notification/ObjectTest.java	2008-07-16 17:30:08 UTC (rev 6310)
+++ pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ObjectTest.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -1,156 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-
-package org.jboss.cache.pojo.notification;
-
-import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertSame;
-import static org.testng.AssertJUnit.assertTrue;
-
-import org.jboss.cache.pojo.PojoCache;
-import org.jboss.cache.pojo.PojoCacheFactory;
-import org.jboss.cache.pojo.notification.event.AttachedEvent;
-import org.jboss.cache.pojo.notification.event.DetachedEvent;
-import org.jboss.cache.pojo.notification.event.Event;
-import org.jboss.cache.pojo.notification.event.FieldModifiedEvent;
-import org.jboss.cache.pojo.test.Address;
-import org.jboss.cache.pojo.test.Person;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-// $Id$
-
-/**
- * Tests attach, detach, and field modify notifications
- *
- * @author Jason T. Greene
- */
- at Test(groups = {"functional"})
-public class ObjectTest
-{
-   protected PojoCache cache;
-   protected Listener listener;
-
-
-   @BeforeMethod(alwaysRun = true)
-   protected void setUp() throws Exception
-   {
-      String configFile = "META-INF/local-service.xml";
-      boolean toStart = false;
-      cache = PojoCacheFactory.createCache(configFile, toStart);
-      cache.start();
-
-      listener = new Listener();
-      cache.addListener(listener);
-   }
-
-   private <T extends Event> T takeNotification(Class<T> clazz)
-   {
-      T notification = listener.take(clazz);
-      verifyNotification(notification);
-
-      return notification;
-   }
-
-   protected void verifyNotification(Event notification)
-   {
-      assertSame(cache, notification.getContext().getPojoCache());
-      assertEquals(true, notification.isLocal());
-   }
-
-
-
-   @AfterMethod(alwaysRun = true)
-   protected void tearDown() throws Exception
-   {
-      cache.stop();
-   }
-
-   public void testAttachNotification() throws Exception
-   {
-      Person test = new Person();
-      test.setName("Ben");
-      test.setAge(10);
-      cache.attach("/a", test);
-      AttachedEvent attach = takeNotification(AttachedEvent.class);
-      assertEquals(test, attach.getSource());
-   }
-
-   public void testAttachNotification2() throws Exception
-   {
-      Person test = new Person();
-      test.setName("Ben");
-      test.setAge(10);
-      Address addr = new Address();
-      test.setAddress(addr);
-      cache.attach("/a", test);
-
-      // Address Attach
-      AttachedEvent attach = takeNotification(AttachedEvent.class);
-      assertEquals(addr, attach.getSource());
-
-      // Person Attach
-      attach = takeNotification(AttachedEvent.class);
-      assertEquals(test, attach.getSource());
-   }
-
-   public void testDetachNotification() throws Exception
-   {
-      Person test = new Person();
-      test.setName("Ben");
-      test.setAge(10);
-      cache.attach("/a", test);
-
-      // Person Attach
-      AttachedEvent attach = takeNotification(AttachedEvent.class);
-      Object attached = attach.getSource();
-      assertEquals(test, attached);
-
-      cache.detach("/a");
-
-      // Person Detach
-      DetachedEvent detach = takeNotification(DetachedEvent.class);
-      assertSame(attached, detach.getSource());
-   }
-
-   public void testFieldNotification() throws Exception
-   {
-      Person test = new Person();
-      test.setName("Ben");
-      test.setAge(10);
-      cache.attach("/a", test);
-
-      // Person Attach
-      AttachedEvent attach = takeNotification(AttachedEvent.class);
-      assertEquals(test, attach.getSource());
-
-      // Field modification
-      test.setAge(20);
-      FieldModifiedEvent modify = takeNotification(FieldModifiedEvent.class);
-      assertEquals(test, modify.getSource());
-      assertEquals(test.getClass().getDeclaredField("age"), modify.getField());
-      assertEquals(20, modify.getValue());
-
-      // Object Field Modification
-      Address addr = new Address();
-      addr.setCity("Madison");
-      addr.setStreet("State St.");
-      addr.setZip(53703);
-      test.setAddress(addr);
-
-      // First Attach
-      attach = takeNotification(AttachedEvent.class);
-      assertEquals(addr, attach.getSource());
-
-      // Then Modify
-      modify = takeNotification(FieldModifiedEvent.class);
-      assertEquals(test, modify.getSource());
-      assertEquals(test.getClass().getDeclaredField("address"), modify.getField());
-      assertEquals(addr, modify.getValue());
-   }
-}
\ No newline at end of file

Copied: pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ObjectTest.java (from rev 6323, pojo/trunk/src/test/java/org/jboss/cache/pojo/notification/ObjectTest.java)
===================================================================
--- pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ObjectTest.java	                        (rev 0)
+++ pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ObjectTest.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -0,0 +1,160 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+package org.jboss.cache.pojo.notification;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertSame;
+import static org.testng.AssertJUnit.assertTrue;
+
+import org.jboss.cache.pojo.PojoCache;
+import org.jboss.cache.pojo.PojoCacheFactory;
+import org.jboss.cache.pojo.notification.event.AttachedEvent;
+import org.jboss.cache.pojo.notification.event.DetachedEvent;
+import org.jboss.cache.pojo.notification.event.Event;
+import org.jboss.cache.pojo.notification.event.FieldModifiedEvent;
+import org.jboss.cache.pojo.test.Address;
+import org.jboss.cache.pojo.test.Person;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+// $Id$
+
+/**
+ * Tests attach, detach, and field modify notifications
+ *
+ * @author Jason T. Greene
+ */
+ at Test(groups = {"functional"})
+public class ObjectTest
+{
+   protected PojoCache cache;
+   protected Listener listener = new Listener();
+
+
+   @BeforeMethod(alwaysRun = true)
+   protected void setUp() throws Exception
+   {
+      String configFile = "META-INF/local-service.xml";
+      boolean toStart = false;
+      cache = PojoCacheFactory.createCache(configFile, toStart);
+      cache.start();
+
+      cache.addListener(listener);
+   }
+
+   private <T extends Event> T takeNotification(Class<T> clazz)
+   {
+      T notification = listener.take(clazz);
+      verifyNotification(notification);
+
+      return notification;
+   }
+
+   protected void verifyNotification(Event notification)
+   {
+      assertSame(cache, notification.getContext().getPojoCache());
+      assertEquals(true, notification.isLocal());
+   }
+
+
+
+   @AfterMethod(alwaysRun = true)
+   protected void tearDown() throws Exception
+   {
+      cache.stop();
+      listener.clear();
+   }
+
+   public void testAttachNotification() throws Exception
+   {
+      Person test = new Person();
+      test.setName("Ben");
+      test.setAge(10);
+      cache.attach("/a", test);
+      AttachedEvent attach = takeNotification(AttachedEvent.class);
+      assertEquals(test, attach.getSource());
+      //cache.detach("/a");
+   }
+
+   public void testAttachNotification2() throws Exception
+   {
+      Person test = new Person();
+      test.setName("Ben");
+      test.setAge(10);
+      Address addr = new Address();
+      test.setAddress(addr);
+      cache.attach("/b", test);
+
+      // Address Attach
+      AttachedEvent attach = takeNotification(AttachedEvent.class);
+      assertEquals(addr, attach.getSource());
+
+      // Person Attach
+      attach = takeNotification(AttachedEvent.class);
+      assertEquals(test, attach.getSource());
+      //cache.detach("/b");
+   }
+
+   public void testDetachNotification() throws Exception
+   {
+      Person test = new Person();
+      test.setName("Ben");
+      test.setAge(10);
+      cache.attach("/c", test);
+
+      // Person Attach
+      AttachedEvent attach = takeNotification(AttachedEvent.class);
+      Object attached = attach.getSource();
+      assertEquals(test, attached);
+
+      cache.detach("/c");
+
+      // Person Detach
+      DetachedEvent detach = takeNotification(DetachedEvent.class);
+      assertSame(attached, detach.getSource());
+   }
+
+   public void testFieldNotification() throws Exception
+   {
+      Person test = new Person();
+      test.setName("Ben");
+      test.setAge(10);
+      cache.attach("/d", test);
+
+      // Person Attach
+      AttachedEvent attach = takeNotification(AttachedEvent.class);
+      assertEquals(test, attach.getSource());
+
+      // Field modification
+      test.setAge(20);
+      FieldModifiedEvent modify = takeNotification(FieldModifiedEvent.class);
+      assertEquals(test, modify.getSource());
+      assertEquals(test.getClass().getDeclaredField("age"), modify.getField());
+      assertEquals(20, modify.getValue());
+
+      // Object Field Modification
+      Address addr = new Address();
+      addr.setCity("Madison");
+      addr.setStreet("State St.");
+      addr.setZip(53703);
+      test.setAddress(addr);
+
+      // First Attach
+      attach = takeNotification(AttachedEvent.class);
+      assertEquals(addr, attach.getSource());
+
+      // Then Modify
+      modify = takeNotification(FieldModifiedEvent.class);
+      assertEquals(test, modify.getSource());
+      assertEquals(test.getClass().getDeclaredField("address"), modify.getField());
+      assertEquals(addr, modify.getValue());
+
+      //cache.detach("/d");
+   }
+}
\ No newline at end of file

Deleted: pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ReplicatedListTest.java
===================================================================
--- pojo/trunk/src/test/java/org/jboss/cache/pojo/notification/ReplicatedListTest.java	2008-07-16 17:30:08 UTC (rev 6310)
+++ pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ReplicatedListTest.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -1,72 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.cache.pojo.notification;
-
-
-import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertSame;
-
-import org.jboss.cache.config.Configuration.CacheMode;
-import org.jboss.cache.factories.UnitTestCacheConfigurationFactory;
-import org.jboss.cache.pojo.PojoCache;
-import org.jboss.cache.pojo.PojoCacheFactory;
-import org.jboss.cache.pojo.notification.event.Event;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-//$Id$
-
-/**
- * Tests replicated list notifications
- *
- * @author Jason T. Greene
- */
- at Test(groups = {"functional"})
-public class ReplicatedListTest extends ListTest
-{
-   private PojoCache listenerCache;
-
-   @BeforeMethod(alwaysRun = true)
-   protected void setUp() throws Exception
-   {
-      cache = PojoCacheFactory.createCache(UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC), false);
-      cache.start();
-      listenerCache = PojoCacheFactory.createCache(UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC), false);
-      listenerCache.start();
-      listenerCache.addListener(listener);
-   }
-
-   @AfterMethod(alwaysRun = true)
-   protected void tearDown() throws Exception
-   {
-      cache.stop();
-      listenerCache.stop();
-      listener.clear();
-   }
-
-   protected void verifyNotification(Event notification)
-   {
-      assertSame(listenerCache, notification.getContext().getPojoCache());
-      assertEquals(false, notification.isLocal());
-   }
-}

Copied: pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ReplicatedListTest.java (from rev 6323, pojo/trunk/src/test/java/org/jboss/cache/pojo/notification/ReplicatedListTest.java)
===================================================================
--- pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ReplicatedListTest.java	                        (rev 0)
+++ pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ReplicatedListTest.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -0,0 +1,77 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.cache.pojo.notification;
+
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertSame;
+
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.config.Configuration.CacheMode;
+import org.jboss.cache.factories.UnitTestCacheConfigurationFactory;
+import org.jboss.cache.pojo.PojoCache;
+import org.jboss.cache.pojo.PojoCacheFactory;
+import org.jboss.cache.pojo.notification.event.Event;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+//$Id$
+
+/**
+ * Tests replicated list notifications
+ *
+ * @author Jason T. Greene
+ */
+ at Test(groups = {"functional"})
+public class ReplicatedListTest extends ListTest
+{
+   private PojoCache listenerCache;
+
+   @BeforeMethod(alwaysRun = true)
+   protected void setUp() throws Exception
+   {
+      Configuration config = UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC);
+      config.setFetchInMemoryState(false);
+      Configuration config2 = UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC);
+      config2.setFetchInMemoryState(false);
+      cache = PojoCacheFactory.createCache(config, false);
+      cache.start();
+      listenerCache = PojoCacheFactory.createCache(config2, false);
+      listenerCache.start();
+      listenerCache.addListener(listener);
+   }
+
+   @AfterMethod(alwaysRun = true)
+   protected void tearDown() throws Exception
+   {
+      cache.stop();
+      listenerCache.stop();
+      listener.clear();
+   }
+
+   protected void verifyNotification(Event notification)
+   {
+      assertSame(listenerCache, notification.getContext().getPojoCache());
+      assertEquals(false, notification.isLocal());
+   }
+}

Deleted: pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ReplicatedMapTest.java
===================================================================
--- pojo/trunk/src/test/java/org/jboss/cache/pojo/notification/ReplicatedMapTest.java	2008-07-16 17:30:08 UTC (rev 6310)
+++ pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ReplicatedMapTest.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -1,76 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.cache.pojo.notification;
-
-
-import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertSame;
-
-import org.jboss.cache.config.Configuration.CacheMode;
-import org.jboss.cache.factories.UnitTestCacheConfigurationFactory;
-import org.jboss.cache.pojo.PojoCache;
-import org.jboss.cache.pojo.PojoCacheFactory;
-import org.jboss.cache.pojo.notification.event.Event;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-//$Id$
-
-/**
- * Tests replicated map notifications
- *
- * @author Jason T. Greene
- */
- at Test(groups = {"functional"})
-public class ReplicatedMapTest extends MapTest
-{
-   private PojoCache listenerCache;
-
-   @BeforeMethod(alwaysRun = true)
-   protected void setUp() throws Exception
-   {
-      super.setUp();
-
-      cache = PojoCacheFactory.createCache(UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC), false);
-      cache.start();
-      listenerCache = PojoCacheFactory.createCache(UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC), false);
-      listenerCache.start();
-      listenerCache.addListener(listener);
-   }
-
-   @AfterMethod(alwaysRun = true)
-   protected void tearDown() throws Exception
-   {
-      super.tearDown();
-      cache.stop();
-      listenerCache.stop();
-   }
-
-   protected void verifyNotification(Event notification)
-   {
-      assertSame(listenerCache, notification.getContext().getPojoCache());
-      assertEquals(false, notification.isLocal());
-   }
-
-
-}

Copied: pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ReplicatedMapTest.java (from rev 6323, pojo/trunk/src/test/java/org/jboss/cache/pojo/notification/ReplicatedMapTest.java)
===================================================================
--- pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ReplicatedMapTest.java	                        (rev 0)
+++ pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ReplicatedMapTest.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -0,0 +1,79 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.cache.pojo.notification;
+
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertSame;
+
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.config.Configuration.CacheMode;
+import org.jboss.cache.factories.UnitTestCacheConfigurationFactory;
+import org.jboss.cache.pojo.PojoCache;
+import org.jboss.cache.pojo.PojoCacheFactory;
+import org.jboss.cache.pojo.notification.event.Event;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+//$Id$
+
+/**
+ * Tests replicated map notifications
+ *
+ * @author Jason T. Greene
+ */
+ at Test(groups = {"functional"})
+public class ReplicatedMapTest extends MapTest
+{
+   private PojoCache listenerCache;
+
+   @BeforeMethod(alwaysRun = true)
+   protected void setUp() throws Exception
+   {
+      Configuration config = UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC);
+      config.setFetchInMemoryState(false);
+      Configuration config2 = UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC);
+      config2.setFetchInMemoryState(false);
+      cache = PojoCacheFactory.createCache(config, false);
+      cache.start();
+      listenerCache = PojoCacheFactory.createCache(config2, false);
+      listenerCache.start();
+      listenerCache.addListener(listener);
+   }
+
+   @AfterMethod(alwaysRun = true)
+   protected void tearDown() throws Exception
+   {
+      cache.stop();
+      listenerCache.stop();
+      listener.clear();
+   }
+
+   protected void verifyNotification(Event notification)
+   {
+      assertSame(listenerCache, notification.getContext().getPojoCache());
+      assertEquals(false, notification.isLocal());
+   }
+
+
+}

Deleted: pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ReplicatedObjectTest.java
===================================================================
--- pojo/trunk/src/test/java/org/jboss/cache/pojo/notification/ReplicatedObjectTest.java	2008-07-16 17:30:08 UTC (rev 6310)
+++ pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ReplicatedObjectTest.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -1,73 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.cache.pojo.notification;
-
-
-import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertSame;
-
-import org.jboss.cache.config.Configuration.CacheMode;
-import org.jboss.cache.factories.UnitTestCacheConfigurationFactory;
-import org.jboss.cache.pojo.PojoCache;
-import org.jboss.cache.pojo.PojoCacheFactory;
-import org.jboss.cache.pojo.notification.event.Event;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-//$Id$
-
-/**
- * Tests replicated set notifications
- *
- * @author Jason T. Greene
- */
- at Test(groups = {"functional"})
-public class ReplicatedObjectTest extends ObjectTest
-{
-   private PojoCache listenerCache;
-
-   @BeforeMethod(alwaysRun = true)
-   protected void setUp() throws Exception
-   {
-      cache = PojoCacheFactory.createCache(UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC), false);
-      cache.start();
-      listenerCache = PojoCacheFactory.createCache(UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC), false);
-      listenerCache.start();
-      listener = new Listener();
-      listenerCache.addListener(listener);
-   }
-   @AfterMethod(alwaysRun = true)
-   protected void tearDown() throws Exception
-   {
-      cache.stop();
-      listenerCache.stop();
-   }
-
-   protected void verifyNotification(Event notification)
-   {
-      assertSame(listenerCache, notification.getContext().getPojoCache());
-      assertEquals(false, notification.isLocal());
-   }
-
-
-}

Copied: pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ReplicatedObjectTest.java (from rev 6323, pojo/trunk/src/test/java/org/jboss/cache/pojo/notification/ReplicatedObjectTest.java)
===================================================================
--- pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ReplicatedObjectTest.java	                        (rev 0)
+++ pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ReplicatedObjectTest.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -0,0 +1,78 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.cache.pojo.notification;
+
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertSame;
+
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.config.Configuration.CacheMode;
+import org.jboss.cache.factories.UnitTestCacheConfigurationFactory;
+import org.jboss.cache.pojo.PojoCache;
+import org.jboss.cache.pojo.PojoCacheFactory;
+import org.jboss.cache.pojo.notification.event.Event;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+//$Id$
+
+/**
+ * Tests replicated set notifications
+ *
+ * @author Jason T. Greene
+ */
+ at Test(groups = {"functional"})
+public class ReplicatedObjectTest extends ObjectTest
+{
+   private PojoCache listenerCache;
+
+   @BeforeMethod(alwaysRun = true)
+   protected void setUp() throws Exception
+   {
+      Configuration config = UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC);
+      config.setFetchInMemoryState(false);
+      Configuration config2 = UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC);
+      config2.setFetchInMemoryState(false);
+      cache = PojoCacheFactory.createCache(config, false);
+      cache.start();
+      listenerCache = PojoCacheFactory.createCache(config2, false);
+      listenerCache.start();
+      listenerCache.addListener(listener);
+   }
+   @AfterMethod(alwaysRun = true)
+   protected void tearDown() throws Exception
+   {
+      cache.stop();
+      listenerCache.stop();
+      listener.clear();
+   }
+
+   protected void verifyNotification(Event notification)
+   {
+      assertSame(listenerCache, notification.getContext().getPojoCache());
+      assertEquals(false, notification.isLocal());
+   }
+
+
+}

Deleted: pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ReplicatedSetTest.java
===================================================================
--- pojo/trunk/src/test/java/org/jboss/cache/pojo/notification/ReplicatedSetTest.java	2008-07-16 17:30:08 UTC (rev 6310)
+++ pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ReplicatedSetTest.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -1,76 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.cache.pojo.notification;
-
-
-import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertSame;
-
-import org.jboss.cache.config.Configuration.CacheMode;
-import org.jboss.cache.factories.UnitTestCacheConfigurationFactory;
-import org.jboss.cache.pojo.PojoCache;
-import org.jboss.cache.pojo.PojoCacheFactory;
-import org.jboss.cache.pojo.notification.event.Event;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-//$Id$
-
-/**
- * Tests replicated set notifications
- *
- * @author Jason T. Greene
- */
- at Test(groups = {"functional"})
-public class ReplicatedSetTest extends ListTest
-{
-   private PojoCache listenerCache;
-
-   @BeforeMethod(alwaysRun = true)
-   protected void setUp() throws Exception
-   {
-      super.setUp();
-
-      cache = PojoCacheFactory.createCache(UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC), false);
-      cache.start();
-      listenerCache = PojoCacheFactory.createCache(UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC), false);
-      listenerCache.start();
-      listenerCache.addListener(listener);
-   }
-
-   @AfterMethod(alwaysRun = true)
-   protected void tearDown() throws Exception
-   {
-      super.tearDown();
-      cache.stop();
-      listenerCache.stop();
-   }
-
-   protected void verifyNotification(Event notification)
-   {
-      assertSame(listenerCache, notification.getContext().getPojoCache());
-      assertEquals(false, notification.isLocal());
-   }
-
-
-}

Copied: pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ReplicatedSetTest.java (from rev 6323, pojo/trunk/src/test/java/org/jboss/cache/pojo/notification/ReplicatedSetTest.java)
===================================================================
--- pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ReplicatedSetTest.java	                        (rev 0)
+++ pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/ReplicatedSetTest.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -0,0 +1,79 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.cache.pojo.notification;
+
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertSame;
+
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.config.Configuration.CacheMode;
+import org.jboss.cache.factories.UnitTestCacheConfigurationFactory;
+import org.jboss.cache.pojo.PojoCache;
+import org.jboss.cache.pojo.PojoCacheFactory;
+import org.jboss.cache.pojo.notification.event.Event;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+//$Id$
+
+/**
+ * Tests replicated set notifications
+ *
+ * @author Jason T. Greene
+ */
+ at Test(groups = {"functional"})
+public class ReplicatedSetTest extends SetTest
+{
+   private PojoCache listenerCache;
+
+   @BeforeMethod(alwaysRun = true)
+   protected void setUp() throws Exception
+   {
+      Configuration config = UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC);
+      config.setFetchInMemoryState(false);
+      Configuration config2 = UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC);
+      config2.setFetchInMemoryState(false);
+      cache = PojoCacheFactory.createCache(config, false);
+      cache.start();
+      listenerCache = PojoCacheFactory.createCache(config2, false);
+      listenerCache.start();
+      listenerCache.addListener(listener);
+   }
+
+   @AfterMethod(alwaysRun = true)
+   protected void tearDown() throws Exception
+   {
+      cache.stop();
+      listenerCache.stop();
+      listener.clear();
+   }
+
+   protected void verifyNotification(Event notification)
+   {
+      assertSame(listenerCache, notification.getContext().getPojoCache());
+      assertEquals(false, notification.isLocal());
+   }
+
+
+}

Deleted: pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/SetTest.java
===================================================================
--- pojo/trunk/src/test/java/org/jboss/cache/pojo/notification/SetTest.java	2008-07-16 17:30:08 UTC (rev 6310)
+++ pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/SetTest.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -1,210 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.cache.pojo.notification;
-
-import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertSame;
-
-import java.util.LinkedHashSet;
-import java.util.Set;
-
-import org.jboss.cache.pojo.PojoCache;
-import org.jboss.cache.pojo.PojoCacheFactory;
-import org.jboss.cache.pojo.notification.event.AttachedEvent;
-import org.jboss.cache.pojo.notification.event.DetachedEvent;
-import org.jboss.cache.pojo.notification.event.Event;
-import org.jboss.cache.pojo.notification.event.SetModifiedEvent;
-import org.jboss.cache.pojo.test.Person;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-//$Id$
-
-/**
- * Tests set notifications
- *
- * @author Jason T. Greene
- */
- at Test(groups = {"functional"})
-public class SetTest 
-{
-   private PojoCache cache;
-   private Listener listener = new Listener();
-
-
-   @BeforeMethod(alwaysRun = true)
-   protected void setUp() throws Exception
-   {
-      String configFile = "META-INF/local-service.xml";
-      boolean toStart = false;
-      cache = PojoCacheFactory.createCache(configFile, toStart);
-      cache.start();
-      cache.addListener(listener);
-   }
-
-   @AfterMethod(alwaysRun = true)
-   protected void tearDown() throws Exception
-   {
-      cache.stop();
-   }
-
-   private <T extends Event> T takeNotification(Class<T> clazz)
-   {
-      T notification = listener.take(clazz);
-      verifyNotification(notification);
-
-      return notification;
-   }
-
-   protected void verifyNotification(Event notification)
-   {
-      assertSame(cache, notification.getContext().getPojoCache());
-      assertEquals(true, notification.isLocal());
-   }
-
-   @SuppressWarnings("unchecked")
-   public void testSetAddNotification() throws Exception
-   {
-      final String test1 = "test1";
-      final String test2 = "test2";
-
-      Set<String> set = new LinkedHashSet<String>();
-      set.add(test1);
-      set.add(test2);
-      cache.attach("a", set);
-      set = (Set) cache.find("a");
-
-      // String attach
-      AttachedEvent attach = takeNotification(AttachedEvent.class);
-      assertEquals(test1, attach.getSource());
-
-      // Set add
-      SetModifiedEvent modify = takeNotification(SetModifiedEvent.class);
-      assertEquals(SetModifiedEvent.Operation.ADD, modify.getOperation());
-      assertEquals(test1, modify.getValue());
-
-      // String attach
-      attach = takeNotification(AttachedEvent.class);
-      assertEquals(test2, attach.getSource());
-
-      // Set add
-      modify = takeNotification(SetModifiedEvent.class);
-      assertEquals(SetModifiedEvent.Operation.ADD, modify.getOperation());
-      assertEquals(test2, modify.getValue());
-
-      // Set Attach
-      attach = takeNotification(AttachedEvent.class);
-      assertSame(set, attach.getSource());
-
-   }
-
-   @SuppressWarnings("unchecked")
-   public void testSetRemoveNotification() throws Exception
-   {
-      final String test1 = "test1";
-      final String test2 = "test2";
-
-      Set<String> set = new LinkedHashSet<String>();
-      set.add(test1);
-      set.add(test2);
-      cache.attach("a", set);
-
-      set = (Set<String>) cache.find("a");
-      set.remove(test2);
-
-      // String attach
-      AttachedEvent attach = takeNotification(AttachedEvent.class);
-      assertEquals(test1, attach.getSource());
-
-      // Set add
-      SetModifiedEvent modify = takeNotification(SetModifiedEvent.class);
-      assertEquals(SetModifiedEvent.Operation.ADD, modify.getOperation());
-      assertEquals(test1, modify.getValue());
-
-      // String attach
-      attach = takeNotification(AttachedEvent.class);
-      assertEquals(test2, attach.getSource());
-
-      // Set add
-      modify = takeNotification(SetModifiedEvent.class);
-      assertEquals(SetModifiedEvent.Operation.ADD, modify.getOperation());
-      assertEquals(test2, modify.getValue());
-
-      // Set Attach
-      attach = takeNotification(AttachedEvent.class);
-      assertSame(set, attach.getSource());
-
-      // Set remove
-      modify = takeNotification(SetModifiedEvent.class);
-      assertEquals(SetModifiedEvent.Operation.REMOVE, modify.getOperation());
-      assertEquals(test2, modify.getValue());
-
-      // String detach
-      DetachedEvent detach = takeNotification(DetachedEvent.class);
-      assertEquals(test2, detach.getSource());
-   }
-
-   public void testObjectSetAdd() throws Exception
-   {
-      final String drumming = "druming";
-      final String engineering = "engineering";
-
-      Person test = new Person();
-      test.setName("Joe");
-      test.setAge(30);
-
-      Set<String> set = new LinkedHashSet<String>();
-      set.add(drumming);
-      set.add(engineering);
-      test.setSkills(set);
-      cache.attach("a", test);
-
-      // String attach
-      AttachedEvent attach = takeNotification(AttachedEvent.class);
-      assertEquals(drumming, attach.getSource());
-
-      // List add
-      SetModifiedEvent modify = takeNotification(SetModifiedEvent.class);
-      assertEquals(SetModifiedEvent.Operation.ADD, modify.getOperation());
-      assertEquals(drumming, modify.getValue());
-
-      // String attach
-      attach = takeNotification(AttachedEvent.class);
-      assertEquals(engineering, attach.getSource());
-
-      // List add
-      modify = takeNotification(SetModifiedEvent.class);
-      assertEquals(SetModifiedEvent.Operation.ADD, modify.getOperation());
-      assertEquals(engineering, modify.getValue());
-
-      // List Attach
-      attach = takeNotification(AttachedEvent.class);
-      assertEquals(test.getSkills(), attach.getSource());
-
-      // Person Attach
-      attach = takeNotification(AttachedEvent.class);
-      assertEquals(test, attach.getSource());
-   }
-
-
-}

Copied: pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/SetTest.java (from rev 6323, pojo/trunk/src/test/java/org/jboss/cache/pojo/notification/SetTest.java)
===================================================================
--- pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/SetTest.java	                        (rev 0)
+++ pojo/tags/2.2.0.CR7/src/test/java/org/jboss/cache/pojo/notification/SetTest.java	2008-08-12 04:16:02 UTC (rev 6554)
@@ -0,0 +1,214 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.cache.pojo.notification;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertSame;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.jboss.cache.pojo.PojoCache;
+import org.jboss.cache.pojo.PojoCacheFactory;
+import org.jboss.cache.pojo.notification.event.AttachedEvent;
+import org.jboss.cache.pojo.notification.event.DetachedEvent;
+import org.jboss.cache.pojo.notification.event.Event;
+import org.jboss.cache.pojo.notification.event.SetModifiedEvent;
+import org.jboss.cache.pojo.test.Person;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+//$Id$
+
+/**
+ * Tests set notifications
+ *
+ * @author Jason T. Greene
+ */
+ at Test(groups = {"functional"})
+public class SetTest
+{
+   protected PojoCache cache;
+   protected Listener listener = new Listener();
+
+
+   @BeforeMethod(alwaysRun = true)
+   protected void setUp() throws Exception
+   {
+      String configFile = "META-INF/local-service.xml";
+      boolean toStart = false;
+      cache = PojoCacheFactory.createCache(configFile, toStart);
+      cache.start();
+      cache.addListener(listener);
+   }
+
+   @AfterMethod(alwaysRun = true)
+   protected void tearDown() throws Exception
+   {
+      cache.stop();
+      listener.clear();
+   }
+
+   private <T extends Event> T takeNotification(Class<T> clazz)
+   {
+      T notification = listener.take(clazz);
+      verifyNotification(notification);
+
+      return notification;
+   }
+
+   protected void verifyNotification(Event notification)
+   {
+      assertSame(cache, notification.getContext().getPojoCache());
+      assertEquals(true, notification.isLocal());
+   }
+
+   @SuppressWarnings("unchecked")
+   public void testSetAddNotification() throws Exception
+   {
+      final String test1 = "test1";
+      final String test2 = "test2";
+
+      Set<String> set = new LinkedHashSet<String>();
+      set.add(test1);
+      set.add(test2);
+      cache.attach("a", set);
+      set = (Set) cache.find("a");
+
+      // String attach
+      AttachedEvent attach = takeNotification(AttachedEvent.class);
+      assertEquals(test1, attach.getSource());
+
+      // Set add
+      SetModifiedEvent modify = takeNotification(SetModifiedEvent.class);
+      assertEquals(SetModifiedEvent.Operation.ADD, modify.getOperation());
+      assertEquals(test1, modify.getValue());
+
+      // String attach
+      attach = takeNotification(AttachedEvent.class);
+      assertEquals(test2, attach.getSource());
+
+      // Set add
+      modify = takeNotification(SetModifiedEvent.class);
+      assertEquals(SetModifiedEvent.Operation.ADD, modify.getOperation());
+      assertEquals(test2, modify.getValue());
+
+      // Set Attach
+      attach = takeNotification(AttachedEvent.class);
+      assertEquals(set, attach.getSource());
+
+      //cache.detach("a");
+   }
+
+   @SuppressWarnings("unchecked")
+   public void testSetRemoveNotification() throws Exception
+   {
+      final String test1 = "test1";
+      final String test2 = "test2";
+
+      Set<String> set = new LinkedHashSet<String>();
+      set.add(test1);
+      set.add(test2);
+      cache.attach("b", set);
+
+      set = (Set<String>) cache.find("b");
+      set.remove(test2);
+
+      // String attach
+      AttachedEvent attach = takeNotification(AttachedEvent.class);
+      assertEquals(test1, attach.getSource());
+
+      // Set add
+      SetModifiedEvent modify = takeNotification(SetModifiedEvent.class);
+      assertEquals(SetModifiedEvent.Operation.ADD, modify.getOperation());
+      assertEquals(test1, modify.getValue());
+
+      // String attach
+      attach = takeNotification(AttachedEvent.class);
+      assertEquals(test2, attach.getSource());
+
+      // Set add
+      modify = takeNotification(SetModifiedEvent.class);
+      assertEquals(SetModifiedEvent.Operation.ADD, modify.getOperation());
+      assertEquals(test2, modify.getValue());
+
+      // Set Attach
+      attach = takeNotification(AttachedEvent.class);
+      assertEquals(set, attach.getSource());
+
+      // Set remove
+      modify = takeNotification(SetModifiedEvent.class);
+      assertEquals(SetModifiedEvent.Operation.REMOVE, modify.getOperation());
+      assertEquals(test2, modify.getValue());
+
+      // String detach
+      DetachedEvent detach = takeNotification(DetachedEvent.class);
+      assertEquals(test2, detach.getSource());
+
+      //cache.detach("b");
+   }
+
+   public void testObjectSetAdd() throws Exception
+   {
+      final String drumming = "druming";
+      final String engineering = "engineering";
+
+      Person test = new Person();
+      test.setName("Joe");
+      test.setAge(30);
+
+      Set<String> set = new LinkedHashSet<String>();
+      set.add(drumming);
+      set.add(engineering);
+      test.setSkills(set);
+      cache.attach("c", test);
+
+      // String attach
+      AttachedEvent attach = takeNotification(AttachedEvent.class);
+      assertEquals(drumming, attach.getSource());
+
+      // List add
+      SetModifiedEvent modify = takeNotification(SetModifiedEvent.class);
+      assertEquals(SetModifiedEvent.Operation.ADD, modify.getOperation());
+      assertEquals(drumming, modify.getValue());
+
+      // String attach
+      attach = takeNotification(AttachedEvent.class);
+      assertEquals(engineering, attach.getSource());
+
+      // List add
+      modify = takeNotification(SetModifiedEvent.class);
+      assertEquals(SetModifiedEvent.Operation.ADD, modify.getOperation());
+      assertEquals(engineering, modify.getValue());
+
+      // List Attach
+      attach = takeNotification(AttachedEvent.class);
+      assertEquals(test.getSkills(), attach.getSource());
+
+      // Person Attach
+      attach = takeNotification(AttachedEvent.class);
+      assertEquals(test, attach.getSource());
+
+      //cache.detach("c");
+   }
+}




More information about the jbosscache-commits mailing list